web-dev-qa-db-ja.com

二分探索と二分探索木の違いは?

バイナリサーチとバイナリサーチツリーの違いは何ですか?

彼らは同じですか?インターネットを読むと、2番目はツリー(最大2つの子ノード)専用であり、バイナリ検索はこのルールに従っていないようです。うまく聞き取れませんでした。

26
RollRoll

二分探索木

バイナリツリーのノードは、要素と、通常は左および右サブツリーと呼ばれる2つの他のバイナリツリーへの参照を持つデータ構造です。つまり、ノードは次のようなインターフェースを提供します。

Node:
  element  (an element of some type)
  left     (a binary tree, or NULL)
  right    (a binary tree, or NULL)

バイナリsearchツリーは、左側と右側のサブツリーもバイナリ検索ツリーであり、すべてのノードのすべての要素であるというプロパティを持つバイナリツリー(つまり、ノード、通常はルートと呼ばれます)です。左側のサブツリーではルートの要素よりも小さく、右側のサブツリーではすべてのノードのすべての要素がルートの要素よりも大きくなっています。例えば。、

     5
    / \
   /   \
  2     8
 / \   / \
1   3 6   9

バイナリ検索

二分探索は、二分探索木の要素を見つけるためのアルゴリズムです。 (これは、順序付けられたコレクションを検索する方法として表現されることが多く、これは同等の説明です。同等性については後で説明します。)これは次のとおりです。

search( element, tree ) {
  if ( tree == NULL ) {
    return NOT_FOUND
  }
  else if ( element == tree.element ) {
    return FOUND_IT
  }
  else if ( element < tree.element ) {
    return search( element, tree.left )
  }
  else {
    return search( element, tree.right )
  }
}

これは通常、各ステップで検索スペースの半分を削除できるため、効率的な検索方法です。もちろん、バランスの悪い二分探索木がある場合、それは非効率的です(線形探索に低下する可能性があります)。たとえば、次のようなツリーではパフォーマンスが低下します。

3
 \
  4
   \
    5
     \
      6

配列の二分探索

バイナリ検索は、ソートされた配列の検索方法として提示されることがよくあります。これは上記の説明と矛盾しません。実際、バイナリ検索ツリーがどのように実装されているかを実際には気にしていないという事実を強調しています。オブジェクトを取得し、それを使用して3つのことを実行できることに注意してください。要素を取得し、左側のサブオブジェクトを取得し、右側のサブオブジェクトを取得します(もちろん、左側の要素に関する制約に従います)要素より小さい、右の要素が大きい、など)。

ソートされた配列を使用して、3つのことすべてを実行できます。並べ替えられた配列の場合、「要素」は配列の中央の要素、左側のサブオブジェクトはその左側のサブ配列、右側のサブオブジェクトはその右側のサブ配列です。例:アレイ

[1 3 4 5 7 8 11]

ツリーに対応:

     5
    / \
   /   \
  3     8
 / \   / \
1  4  7   11

したがって、次のような配列のバイナリ検索メソッドを作成できます。

search( element, array, begin, end ) {
  if ( end <= begin ) {
    return NOT_FOUND
  }
  else { 
    midpoint = begin+(end-begin)/2
    a_element = array[midpoint]
    if ( element == midpoint ) {
      return FOUND_IT
    }
    else if ( element < midpoint ) {
      return search( element, array, begin, midpoint )
    }
    else {
      return search( element, array, midpoint, end )
    }
  }
}

結論

しばしば提示されるように、二分探索はここに提示された配列ベースのアルゴリズムを指し、二分探索ツリーは特定のプロパティを持つツリーベースのデータ構造を指します。ただし、バイナリサーチに必要なプロパティとバイナリサーチツリーが持つプロパティにより、これらの2つの面が同じコインになります。二分探索木であることはしばしば特定の実装を意味しますが、実際には特定の操作を提供し、特定の制約を満たすことが問題です。二分探索は、これらの演算を持ち、これらの制約を満たすデータ構造で機能するアルゴリズムです。

34
Joshua Taylor

いいえ、同じではありません。

二分探索木

  • ツリーデータ構造
  • 各ノードには最大2つの子があります
  • ノードの左側のサブツリーには、ノードのキーより小さいキーを持つノードのみが含まれます
  • ノードの右側のサブツリーには、ノードのキーより大きいキーを持つノードのみが含まれます

二分探索

  • アルゴリズムは、ソートされたデータ構造(通常は配列ですが、必ずしもそうではありません)で機能し、各ステップで中央の値を確認しますターゲット値が中央の値よりも小さいか大きいかに応じて、左または右に再帰します(または、等しい場合は停止します)。

そしてもちろん、 データ構造 は:

コンピューターでデータを効率的に使用できるように保存および整理する特定の方法。

アルゴリズム は次のとおりです。

計算のための段階的な手順。

二分探索木(木の特定の値を探す場所)のsearchプロセスは、定義に応じて(またはのインスタンスに)似ていると考えることができます。バランスBST)バイナリ検索を使用しているかどうか。これは、「中央」要素も調べて、その値とターゲット値の比較結果に応じて、左または右に再帰するためです。

11
Dukeling

どれを使うかをすぐに確認するためにここに来た人のために。上記の回答に加えて、これらの両方の手法の操作に関して複雑さを追加したいと思います。

二分探索木:

検索θ(log(n))、最悪の場合(O(n))不均衡BST、

挿入ノード:θ(log(n))、最悪の場合(O(n)) forアンバランスBST

削除ノードの:θ(log(n))、、最悪の場合(O(n))アンバランスBSTの場合

バランスの取れたバイナリ検索ツリー:

検索ログ(n)

挿入ノード:O(log(n))

削除ノードの:O(log(n))

ソートされた配列のバイナリ検索:

検索O(log(n))しかし、

挿入ノード:配列が静的に割り当てられており、すでに満杯である場合は不可能です。それ以外の場合O(n)O(n)配列のより大きな項目を隣接する右に移動する場合)

削除ノードの:O(log(n))+ O(n)。 (つまり、O(log(n))削除の位置を見つける場合+ O(n)配列のより大きな項目を隣接する左に移動する場合)

したがって、要件に基づいて、クイック挿入と削除が必要かどうかを選択できます。これらが必要ない場合は、並べ替えられた配列に物を保管しておくとうまくいきます。これは、配列がツリーに比べてメモリの消費が少ないため

3
Alok Nayak