mirror of
https://github.com/krahets/hello-algo.git
synced 2026-08-13 04:10:58 +00:00
Re-translate the Japanese version (#1871)
* Retranslate Japanese docs with GPT-5.4 * Retranslate Japanese code with GPT-5.4
This commit is contained in:
@@ -1,84 +1,84 @@
|
||||
# 探索アルゴリズムの再検討
|
||||
# 探索アルゴリズム再考
|
||||
|
||||
<u>探索アルゴリズム(検索アルゴリズム)</u>は、配列、連結リスト、木、グラフなどのデータ構造内で特定の基準を満たす1つ以上の要素を取得するために使用されます。
|
||||
<u>探索アルゴリズム(searching algorithm)</u>は、データ構造(配列、連結リスト、木、グラフなど)の中から、特定の条件を満たす 1 つまたは複数の要素を探索するために用いられます。
|
||||
|
||||
探索アルゴリズムは、そのアプローチに基づいて以下の2つのカテゴリに分けることができます。
|
||||
探索アルゴリズムは、実装の考え方に応じて次の 2 種類に分けられます。
|
||||
|
||||
- **データ構造を横断することで目標要素を特定する**:配列、連結リスト、木、グラフの横断など。
|
||||
- **データの組織構造や既存のデータを使用して効率的な要素探索を実現する**:二分探索、ハッシュ探索、二分探索木探索など。
|
||||
- **データ構造を走査して目標要素を特定する方法**。配列、連結リスト、木、グラフの走査などがこれに当たります。
|
||||
- **データの構成やデータに含まれる事前情報を利用して、要素を効率よく探す方法**。二分探索、ハッシュ探索、二分探索木による探索などがこれに当たります。
|
||||
|
||||
これらのトピックは前の章で紹介されたため、私たちには馴染みのないものではありません。このセクションでは、より体系的な観点から探索アルゴリズムを再検討します。
|
||||
これらのトピックはすでに前の章で扱っているため、探索アルゴリズムは私たちにとって見慣れたものです。本節では、より体系的な視点から探索アルゴリズムをあらためて見直します。
|
||||
|
||||
## 総当たり探索
|
||||
|
||||
総当たり探索は、データ構造のすべての要素を横断することで目標要素を特定します。
|
||||
総当たり探索は、データ構造の各要素を順に調べて目標要素を特定します。
|
||||
|
||||
- 「線形探索」は配列や連結リストなどの線形データ構造に適しています。データ構造の一端から開始し、目標要素が見つかるか、目標要素を見つけることなく他端に到達するまで、各要素に一つずつアクセスします。
|
||||
- 「幅優先探索」と「深さ優先探索」は、グラフと木の2つの横断戦略です。幅優先探索は初期ノードから開始し、層ごと(左から右へ)に探索し、近くから遠くのノードにアクセスします。深さ優先探索は初期ノードから開始し、パスの終端(上から下へ)まで追跡し、その後バックトラックして他のパスを試し、データ構造全体が横断されるまで続行します。
|
||||
- “線形探索”は配列や連結リストなどの線形データ構造に適しています。データ構造の一端から始めて、要素を 1 つずつ調べ、目標要素が見つかるか、もう一方の端に達しても見つからないまで続けます。
|
||||
- “幅優先探索”と“深さ優先探索”は、グラフと木における 2 つの走査戦略です。幅優先探索は初期ノードから始めて層ごとに探索し、近いところから遠いところへ各ノードを訪れます。深さ優先探索は初期ノードから始めて 1 本の経路を最後までたどり、その後でバックトラックしてほかの経路を試し、データ構造全体を走査し終えるまで続けます。
|
||||
|
||||
総当たり探索の利点は、その単純さと汎用性であり、**データの前処理や追加のデータ構造の助けが不要**です。
|
||||
総当たり探索の利点は、単純で汎用性が高く、**データの前処理や追加のデータ構造を必要としない**ことです。
|
||||
|
||||
ただし、**このタイプのアルゴリズムの時間計算量は$O(n)$**で、$n$は要素数であるため、大規模なデータセットでは性能が悪くなります。
|
||||
しかし、**この種のアルゴリズムの時間計算量は $O(n)$ です**。ここで $n$ は要素数であり、そのためデータ量が大きい場合は性能が低くなります。
|
||||
|
||||
## 適応的探索
|
||||
## 適応的な探索
|
||||
|
||||
適応的探索は、データの固有の性質(順序など)を使用して探索プロセスを最適化し、それにより目標要素をより効率的に特定します。
|
||||
適応的な探索は、データが持つ固有の性質(整列性など)を利用して探索過程を最適化し、目標要素をより効率よく特定します。
|
||||
|
||||
- 「二分探索」はデータの整列性を使用して効率的な探索を実現し、配列にのみ適用可能です。
|
||||
- 「ハッシュ探索」はハッシュテーブルを使用して探索データと目標データの間にキーと値のマッピングを確立し、それによりクエリ操作を実装します。
|
||||
- 特定の木構造(二分探索木など)での「木探索」は、ノード値の比較に基づいてノードを迅速に除外し、それにより目標要素を特定します。
|
||||
- “二分探索”は、データの順序性を利用して効率的な探索を行う方法で、配列にしか適用できません。
|
||||
- “ハッシュ探索”は、ハッシュ表を用いて探索対象のデータと目標データをキーと値の対応にし、問い合わせ操作を実現します。
|
||||
- “木探索”は、特定の木構造(たとえば二分探索木)の中で、ノード値の比較に基づいて不要なノードをすばやく除外し、目標要素を特定します。
|
||||
|
||||
これらのアルゴリズムの利点は高効率であり、**時間計算量が$O(\log n)$または$O(1)$にまで達します**。
|
||||
この種のアルゴリズムの利点は効率が高く、**時間計算量が $O(\log n)$ あるいは $O(1)$ に達する**ことです。
|
||||
|
||||
ただし、**これらのアルゴリズムを使用するには、多くの場合データの前処理が必要です**。例えば、二分探索では事前に配列をソートする必要があり、ハッシュ探索と木探索の両方で追加のデータ構造の助けが必要です。これらの構造を維持することも、時間と空間の面でより多くのオーバーヘッドが必要です。
|
||||
しかし、**これらのアルゴリズムを使うには、たいていデータの前処理が必要です**。たとえば、二分探索では事前に配列をソートする必要があり、ハッシュ探索と木探索では追加のデータ構造が必要です。これらのデータ構造を維持するにも、追加の時間と空間のコストがかかります。
|
||||
|
||||
!!! tip
|
||||
|
||||
適応的探索アルゴリズムは、多くの場合探索アルゴリズムと呼ばれ、**主に特定のデータ構造内で目標要素を迅速に取得するために使用されます**。
|
||||
適応的な探索アルゴリズムは、しばしば検索アルゴリズムとも呼ばれ、**主に特定のデータ構造の中で目標要素を高速に取得するために用いられます**。
|
||||
|
||||
## 探索方法の選択
|
||||
## 探索手法の選択
|
||||
|
||||
サイズ$n$のデータセットが与えられた場合、線形探索、二分探索、木探索、ハッシュ探索、またはその他の方法を使用して目標要素を取得できます。これらの方法の動作原理を下図に示します。
|
||||
大きさ $n$ のデータ集合が与えられたとき、線形探索、二分探索、木探索、ハッシュ探索など、さまざまな方法で目標要素を探索できます。各手法の動作原理を下図に示します。
|
||||
|
||||

|
||||

|
||||
|
||||
前述の方法の特性と操作効率を以下の表に示します。
|
||||
上記のいくつかの手法について、操作効率と特性を次の表に示します。
|
||||
|
||||
<p align="center"> 表 <id> 探索アルゴリズム効率の比較 </p>
|
||||
<p align="center"> 表 <id> 探索アルゴリズムの効率比較 </p>
|
||||
|
||||
| | 線形探索 | 二分探索 | 木探索 | ハッシュ探索 |
|
||||
| ------------------ | ------------- | --------------------- | --------------------------- | -------------------------- |
|
||||
| 要素探索 | $O(n)$ | $O(\log n)$ | $O(\log n)$ | $O(1)$ |
|
||||
| 要素挿入 | $O(1)$ | $O(n)$ | $O(\log n)$ | $O(1)$ |
|
||||
| 要素削除 | $O(n)$ | $O(n)$ | $O(\log n)$ | $O(1)$ |
|
||||
| 追加空間 | $O(1)$ | $O(1)$ | $O(n)$ | $O(n)$ |
|
||||
| データ前処理 | / | ソート $O(n \log n)$ | 木構築 $O(n \log n)$ | ハッシュテーブル構築 $O(n)$ |
|
||||
| データ順序性 | 無順序 | 順序 | 順序 | 無順序 |
|
||||
| | 線形探索 | 二分探索 | 木探索 | ハッシュ探索 |
|
||||
| ------------ | -------- | ------------------ | ------------------ | --------------- |
|
||||
| 要素探索 | $O(n)$ | $O(\log n)$ | $O(\log n)$ | $O(1)$ |
|
||||
| 要素挿入 | $O(1)$ | $O(n)$ | $O(\log n)$ | $O(1)$ |
|
||||
| 要素削除 | $O(n)$ | $O(n)$ | $O(\log n)$ | $O(1)$ |
|
||||
| 追加領域 | $O(1)$ | $O(1)$ | $O(n)$ | $O(n)$ |
|
||||
| データ前処理 | / | ソート $O(n \log n)$ | 木構築 $O(n \log n)$ | ハッシュ表構築 $O(n)$ |
|
||||
| データの順序性 | なし | あり | あり | なし |
|
||||
|
||||
探索アルゴリズムの選択は、データ量、探索性能要件、データクエリと更新の頻度などにも依存します。
|
||||
探索アルゴリズムの選択は、規模、探索性能の要求、データの問い合わせ頻度や更新頻度などにも左右されます。
|
||||
|
||||
**線形探索**
|
||||
|
||||
- 汎用性が良く、データ前処理操作が不要です。データを一度だけクエリする必要がある場合、他の3つの方法のデータ前処理時間は線形探索の時間よりも長くなります。
|
||||
- 小容量のデータに適しており、時間計算量が効率に与える影響は小さいです。
|
||||
- データ更新が非常に頻繁なシナリオに適しています。この方法はデータの追加メンテナンスを必要としないためです。
|
||||
- 汎用性が高く、データの前処理をまったく必要としません。データを 1 回だけ問い合わせればよい場合、ほか 3 つの手法では前処理にかかる時間のほうが、線形探索そのものより長くなることがあります。
|
||||
- 規模の小さいデータに適しています。この場合、時間計算量が効率に与える影響は比較的小さいです。
|
||||
- データ更新頻度が高い場面に適しています。この手法では、データに対する追加の保守が不要だからです。
|
||||
|
||||
**二分探索**
|
||||
|
||||
- より大きなデータ量に適しており、安定した性能と最悪ケースの時間計算量$O(\log n)$を持ちます。
|
||||
- ただし、データ量が大きすぎることはできません。配列の保存には連続したメモリ空間が必要だからです。
|
||||
- 頻繁な追加と削除があるシナリオには適していません。順序付き配列の維持に多くのオーバーヘッドが発生するためです。
|
||||
- 大規模データに適しており、効率が安定しています。最悪時間計算量は $O(\log n)$ です。
|
||||
- データ量が大きすぎる場合には向きません。配列の格納には連続したメモリ領域が必要だからです。
|
||||
- 頻繁な挿入・削除がある場面には向きません。整列配列を維持するコストが高いためです。
|
||||
|
||||
**ハッシュ探索**
|
||||
|
||||
- 高速クエリ性能が不可欠なシナリオに適しており、平均時間計算量は$O(1)$です。
|
||||
- 順序付きデータや範囲探索が必要なシナリオには適していません。ハッシュテーブルはデータの順序性を維持できないためです。
|
||||
- 問い合わせ性能への要求が高い場面に適しており、平均時間計算量は $O(1)$ です。
|
||||
- 順序付きデータや範囲探索が必要な場面には向きません。ハッシュ表ではデータの順序性を維持できないからです。
|
||||
- ハッシュ関数とハッシュ衝突処理戦略への依存度が高く、性能劣化のリスクが大きいです。
|
||||
- 過度に大容量のデータには適していません。ハッシュテーブルは衝突を最小化し、良好なクエリ性能を提供するために追加の空間が必要だからです。
|
||||
- データ量が大きすぎる場合には向きません。ハッシュ表は衝突をできるだけ減らして良好な問い合わせ性能を出すために、追加の空間を必要とするからです。
|
||||
|
||||
**木探索**
|
||||
|
||||
- 大容量データに適しています。木ノードはメモリ内に分散して保存されるためです。
|
||||
- 順序付きデータの維持や範囲探索に適しています。
|
||||
- ノードの継続的な追加と削除により、二分探索木は偏る可能性があり、時間計算量が$O(n)$に劣化する可能性があります。
|
||||
- AVL木や赤黒木を使用する場合、操作は$O(\log n)$効率で安定して実行できますが、木のバランスを維持する操作により追加のオーバーヘッドが追加されます。
|
||||
- 巨大データに適しています。木ノードはメモリ上に分散して格納されるためです。
|
||||
- 順序付きデータの維持や範囲探索が必要な場面に適しています。
|
||||
- ノードの挿入・削除を続ける過程で、二分探索木は偏ることがあり、時間計算量は $O(n)$ まで劣化する可能性があります。
|
||||
- AVL 木や赤黒木を使えば、各種操作を $O(\log n)$ の効率で安定して実行できますが、木の平衡を保つ処理による追加コストが発生します。
|
||||
|
||||
Reference in New Issue
Block a user