C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++プログラムにおける二分探索(バイナリサーチ)の基本と実装

二分探索(バイナリサーチ)とは

二分探索は「半区間探索」「対数探索」「バイナリチョップ」とも呼ばれる検索アルゴリズムで、ソート済みの配列の中から目的の値が存在する位置を効率的に見つけ出します。

基本的な仕組みは非常にシンプルです。まず、探したい値(ターゲット値)を配列の中央の要素と比較します。一致しなかった場合は、ターゲット値が存在し得ない半分を丸ごと排除し、残りの半分に対して同様の比較を繰り返します。この「中央との比較」と「範囲の絞り込み」を続け、ターゲット値が見つかるか、検索範囲が空になる(=配列にその値が存在しない)かのどちらかで処理が終了します。

アイデア自体は簡単ですが、正しく実装するには終了条件中間点の計算方法など、いくつかの細かい点への注意が必要です。特に、配列内の値が整数範囲全体を網羅していない場合には慎重な設計が求められます。

二分探索が選ばれる理由

二分探索は最も人気のある検索アルゴリズムの一つです。高速かつ効率的であり、さまざまな問題を解決する際に頻繁に活用される定番テクニックでもあります。

たとえば、世界中の人名をすべて順番に並べたリストから特定の名前の位置を探す場合でも、二分探索なら最大35回程度の反復で見つけ出すことができます。

前提条件:データがソートされていること

二分探索が機能するのは、要素がソートされた集合のみです。コレクションに二分探索を適用するには、事前に必ずソートしておく必要があります。

ソート済みの集合に対して二分探索を使用すれば、検索対象の値に応じて反復回数を常に削減できます。

具体例で理解する二分探索

次のような配列を考えてみましょう。

C++プログラムにおける二分探索(バイナリサーチ)の基本と実装

線形探索の場合、要素「8」の位置が判明するのは9回目の反復になります。

では、二分探索を使うと反復回数がどのように減るのかを見ていきましょう。検索を開始する前に、検索範囲の始まりと終わりを把握しておく必要があります。それぞれ「Low(下限)」「High(上限)」と呼びます。

Low = 0
High = n-1

次に、検索値 K を下限と上限の中間位置にある要素と比較します。K の方が大きければ下限を引き上げ、小さければ上限を引き下げます。

C++プログラムにおける二分探索(バイナリサーチ)の基本と実装

上の図では、下限が 0、上限が 9 です。

下限と上限の中間点は (lower_bound + upper_bound) / 2 = 4 となります。ここで a[4] = 4 です。この値 4 は、探している値 2 より大きいため、インデックス 4 より先の要素を調べる必要はありません。それ以降の要素は明らかに 2 より大きくなるからです。

したがって、配列の上限を要素 4 の位置まで切り詰めることができます。同じ手順を、次の範囲設定で再度適用します。

Low: 0
High: 3

この手順を再帰的に繰り返し、「Low > High」となった時点で終了します。途中の反復で a[mid] == key となれば mid の値を返します。これが配列内における key の位置です。key が配列に存在しない場合は -1 を返します。

C++による実装例

int binarySearch(int low, int high, int key){
    while(low <= high){
        int mid = (low + high) / 2;
        if(a[mid] < key){
            low = mid + 1;
        }
        else if(a[mid] > key){
            high = mid - 1;
        }
        else{
            return mid;
        }
    }
    return -1; // キーが見つからなかった場合
}
  1. C++で二分探索木(AVL木)の左回転を実装するプログラム

    二分探索木とは二分探索木(Binary Search Tree)とは、すべてのノードが次の性質を満たすソート済みの二分木です。ノードの右部分木には、親ノードのキーより大きいキーがすべて格納されるノードの左部分木には、親ノードのキーより小さいキーがすべて格納される各ノードが持てる子ノードは最大2つまで木の回転(Tree Rotation)とは木の回転とは、二分木の要素の順序(ソート順)を崩すことなく木の構造を変更する操作です。回転では、あるノードを1つ上へ、別のノードを1つ下へ移動させます。回転は木の形状を変えるために使われ、小さな部分木を下へ、大きな部分木を上へ移動することで木の高さを抑えられ

  2. C#で二分探索(バイナリサーチ)を実装する方法|仕組みと計算量を解説

    二分探索とは二分探索(バイナリサーチ)は、ソート済みの配列を対象とした高速な検索アルゴリズムです。探索したい値を配列の中央にある要素と比較し、一致しなかった場合は、その値が存在し得ない側の半分の領域を丸ごと除外します。この操作を残りの半分に対して繰り返すことで、効率よく目的の値を見つけ出します。例えば、下図のような配列から「62」という値を探す場合を考えてみましょう。中央の要素との比較結果から、62が存在するのは右側の領域だけであることが分かるため、左半分は完全に除外され、以降は右半分のみが探索対象となります。二分探索の計算量二分探索における各ケースの計算量は以下の通りです。最悪時間計算量O(