アルゴリズムの授業

1. 線形探索 (Linear Search)

1.1 概要

配列(またはリスト)の先頭から順番に目標値と比較し、一致したらその位置を返す。見つからなければ最後まで調べ終えて「未発見」を返す。

1.2 計算量

1.3 特徴・利点・欠点

1.4 実装例 (C++)

// 配列 arr[n] の中から key を線形探索し、見つかればそのインデックスを、
// 見つからなければ -1 を返す
int linearSearch(const std::vector<int>& arr, int key) {
    for (size_t i = 0; i < arr.size(); ++i) {
        if (arr[i] == key) {
            return static_cast<int>(i);
        }
    }
    return -1;
}

1.5 適用場面


2. 二分探索 (Binary Search)

2.1 概要

ソート済み配列の中央要素と比較し、目標値が小さければ左半分、大きければ右半分を再帰的(またはループ)に探索。範囲を半分ずつ絞っていく。

2.2 計算量

2.3 特徴・利点・欠点

2.4 実装例 (C++)

// ソート済み vector の二分探索
int binarySearch(const std::vector<int>& arr, int key) {
    int left = 0;
    int right = static_cast<int>(arr.size()) - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (arr[mid] == key) {
            return mid;
        } else if (arr[mid] < key) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return -1;
}

2.5 適用場面


3. ハッシュ探索 (Hash Search)

3.1 概要

ハッシュ関数でキーからテーブルの領域(バケット)を計算し、直接アクセス。バケット内はリストや連想配列で衝突解消(チェイニング、オープンアドレスなど)する。

3.2 計算量

3.3 特徴・利点・欠点

3.4 実装例 (C++ 標準ライブラリ利用)

#include <unordered_map>

// key -> value のマップを作成し、検索
int hashSearch(const std::unordered_map<int, std::string>& mp, int key) {
    auto it = mp.find(key);
    if (it != mp.end()) {
        // 見つかったら値を参照できる
        return it->second;
    }
    // 見つからない
    throw std::out_of_range("キーが存在しません");
}

3.5 適用場面


4. 比較まとめ

特徴

線形探索

二分探索

ハッシュ探索

前提条件

なし

ソート済み

なし

平均時間計算量

O(n)

O(log n)

O(1)

最悪時間計算量

O(n)

O(log n)

O(n)

空間オーバーヘッド

ほぼゼロ

ほぼゼロ

テーブル分あり

実装の易しさ

◎(簡単)

○(やや注意)

△(ハッシュ設計)

用途

小規模or単発探索

大規模かつ静的

動的なキー/値管理


5. 使い分けのポイント


もしそれぞれの詳しい応用例や、別の言語での実装例、あるいは木構造探索(B木・AVL木など)についてもご興味があれば、ぜひお知らせください。

あなた:

ぎりぎりC言語しか勉強していない人がわかる疑似言語表記で、それぞれのアルゴリズムを説明してみてほしい。

ChatGPT:

了解です!
C言語に慣れている人がすんなり読めるように、「C言語風の疑似コード(変数宣言あり、for・if中心、関数呼び出しも明示)」で、
以下3つの探索アルゴリズムを順に説明します。


🔍 1. 線形探索(Linear Search)

● 概要

先頭から順番に調べていって、見つかったらその位置(インデックス)を返す。

● 疑似コード(C風)

int linear_search(int arr[], int size, int key) {
    int i;

    for (i = 0; i < size; i++) {
        if (arr[i] == key) {
            return i; // 見つかったのでその位置を返す
        }
    }

    return -1; // 最後まで見つからなかった
}

● 説明ポイント


🌓 2. 二分探索(Binary Search)

● 概要

中央を調べて、半分ずつ範囲を狭めていく方法(※配列がソートされている必要あり)

● 疑似コード(C風)

int binary_search(int arr[], int size, int key) {
    int left = 0;
    int right = size - 1;

    while (left <= right) {
        int mid = (left + right) / 2;

        if (arr[mid] == key) {
            return mid; // 見つかった
        } else if (arr[mid] < key) {
            left = mid + 1; // 右半分を探す
        } else {
            right = mid - 1; // 左半分を探す
        }
    }

    return -1; // 見つからない
}

● 説明ポイント


🔳 3. ハッシュ探索(Hash Search)

● 概要

値(key)を使って、直接「探す場所(インデックス)」を計算する方法
→ 計算式: index = hash_function(key)

※ここでは衝突がない簡易な例として説明します

● 疑似コード(C風:簡易ハッシュテーブル使用)

#define TABLE_SIZE 10

int hash_function(int key) {
    return key % TABLE_SIZE;
}

int hash_table[TABLE_SIZE]; // 値を保存するテーブル

void insert(int key) {
    int index = hash_function(key);
    hash_table[index] = key; // ※衝突処理は省略
}

int hash_search(int key) {
    int index = hash_function(key);
    if (hash_table[index] == key) {
        return index; // 見つかった
    } else {
        return -1; // 見つからない or 衝突で上書きされた
    }
}

● 説明ポイント


✨ 比較まとめ(覚えやすく)

種類

ソート必要

速さ(目安)

簡単さ

特徴

線形探索

不要

遅い O(n)

◎ 簡単

一番素直な方法

二分探索

必要

速い O(log n)

○ 普通

中央から半分に絞っていく

ハッシュ探索

不要

速い O(1)

△ やや難

直接位置を計算して探す




Revision #1
Created 16 July 2025 00:04:12 by youe2
Updated 2 June 2026 18:59:18 by youe2