web-dev-qa-db-ja.com

線形検索とバイナリ検索の違いは何ですか?

線形検索とバイナリ検索の違いは何ですか?

42
Smi

線形検索 は、ジャンプせずに一度に1項目ずつリストを検索します。複雑さの用語では、これはO(n)検索です-リストの検索にかかる時間は、リストと同じ速度で大きくなります。

バイナリ検索 は、ソートされたリストの中央から開始し、それが探している値よりも大きいか小さいかを調べ、値が最初か2番目かを決定する場合です。リストの半分。これは、人間が辞書でWordを検索する一般的な方法です(明らかに、より良いヒューリスティックを使用していますが、「猫」を探している場合は、 「M」で開始)。複雑さの観点では、これはO(log n)検索です-各操作で「検索スペース」が半分になるため、検索操作の数はリストよりもゆっくりと増加します。

例として、A〜Zの文字のリストでUを探していたと仮定します(インデックス0〜25。インデックス20の値を探しています)。

線形検索では次のように求められます。

list[0] == 'U'?番号。
list[1] == 'U'?番号。
list[2] == 'U'?番号。
list[3] == 'U'?番号。
list[4] == 'U'?番号。
list[5] == 'U'?番号。
... list[20] == 'U'?はい。終わった。

バイナリ検索では次のように求められます。

list[12]( 'M')と 'U'を比較:小さく、さらに調べてください。 (範囲= 13-25)
list[19]( 'T')と 'U'の比較:小さく、詳しく見てください。 (範囲= 20-25)
list[22]( 'W')と 'U'を比較:大きく、先に見てください。 (範囲= 20-21)
list[20]( 'U')と 'U'を比較:見つけました!終わった。

2つの比較:

  • バイナリ検索では、入力データを並べ替える必要があります。線形検索はしません
  • バイナリ検索にはordering比較が必要です。線形検索には等値比較のみが必要です
  • バイナリ検索の複雑さはO(log n)です。前述のように、線形検索には複雑さO(n)があります
  • バイナリ検索には、データへのランダムアクセスが必要です。線形検索はシーケンシャルアクセスのみを必要とします(これは非常に重要です-これは線形検索がstreamデータの任意のサイズを意味します)
111
Jon Skeet

電話帳で自分の道を見つける2つの異なる方法と考えてください。線形検索は最初から始まり、探しているものが見つかるまですべての名前を読み取ります。一方、バイナリ検索では、ブックを開いて(通常は中央)、ページの上部にある名前を見て、探している名前が自分の名前よりも大きいか小さいかを判断します。探しています。探している名前が大きい場合、この方法で本の上部を検索し続けます。

61
Mia Clarke

線形検索は、ターゲットが見つかるか最後に達するまで、データのリスト内の各要素を調べることで機能します。これにより、特定のリストでO(n)パフォーマンスが得られます。バイナリ検索には、データを並べ替える必要があるという前提条件があります。この情報を活用して、ターゲットを見つけるために調べる必要があるアイテムの数を減らすことができます。データ内のランダムなアイテム(中央のアイテム)を見て、そのアイテムがターゲットよりも大きい場合、そのアイテムの右側にあるすべてのアイテムもターゲットよりも大きいことがわかります。これは、データの左側部分のみを見る必要があることを意味します。基本的に、ターゲットを検索してミスするたびに、残りのアイテムの半分を削除できます。これにより、Nice O(log n)時間の複雑さが与えられます。

最も効率的なアルゴリズムであっても、データの並べ替えは常に線形検索よりも遅いことに注意してください(最も速い並べ替えアルゴリズムはO(n * log n)です)。したがって、後で単一のバイナリ検索を実行するためだけにデータをソートすることはできません。ただし、多くの検索(少なくともO(log n)検索など)を実行する場合は、バイナリ検索を実行できるようにデータを並べ替える価値があります。このような状況では、ハッシュテーブルなどの他のデータ構造も考慮する必要があります。

14
antar

線形検索は、値のリストの先頭から始まり、探している結果を得るために1つずつチェックします。

バイナリ検索は、ソートされた配列の中央で開始され、探している値がどちら側にあるか(ある場合)を判別します。次に、配列のその「半分」が同じ方法で再度検索され、結果が毎回半分に分割されます。

5
jthompson

(バイナリ検索を使用できるようにするために)より高速なバイナリ検索の勝利がリストのソートを維持するコストに見合うかどうかを必ず検討してください。つまり多くの挿入/削除操作があり、たまにしか検索しない場合、バイナリ検索は線形検索よりも全体的に遅くなる可能性があります。

5
knweiss

これを試してください:ランダムな名前「Lastname、Firstname」を選んで、電話帳で調べてください。

1回目:本の冒頭から始めて、名前が見つかるまで読みます。そうでない場合は、アルファベット順に出現する場所を見つけ、そこにないことに注意します。

2回目:途中で本を開き、ページを見てください。この人が左にいるのか右にいるのか、考えてみてください。どちらでも、その1/2を取り、その真ん中を見つけます。エントリが存在するページが見つかるまでこの手順を繰り返し、その後、同じプロセスを列に適用するか、以前と同様にページ上の名前に沿って直線的に検索します。

両方の方法で時間を計って報告してください!

[もしあなたが持っているのがソートされていない名前のリストであるなら、どのアプローチがより良いかを考慮してください...]

3
simon

線形検索では、ジャンプすることなく、一度に1項目ずつリストを検索します。複雑さの用語では、これはO(n)検索です-リストの検索にかかる時間は、リストと同じ速度で大きくなります。

バイナリ検索は、並べ替えられたリストの中央から開始し、それが探している値よりも大きいか小さいかを確認することです。これにより、値がリストの前半か後半かが決まります。これは、人間が辞書でWordを検索する一般的な方法です(明らかに、より良いヒューリスティックを使用していますが、「猫」を探している場合は、 「M」で始まります)。複雑な用語では、これはO(log n)検索です。検索操作の数は、各操作で「検索スペース」を半分にしているため、リストよりもゆっくりと増加します。

2
Vijay

バイナリ検索はO(logn)時間で実行されますが、線形検索はO(n)時間で実行されるため、バイナリ検索のパフォーマンスが向上します

2
Vijay

線形検索とも呼ばれる線形検索は、最初から順番に各要素を調べて、目的の要素がデータ構造に存在するかどうかを確認します。データの量が少ない場合、この検索は高速です。簡単ですが、必要な作業は検索するデータの量に比例します。要素の数を2倍にすると、目的の要素が存在しない場合に検索時間が2倍になります。

バイナリ検索は、より大きな配列に対して効率的です。これで、中間の要素をチェックします。値が探している値よりも大きい場合は、前半を調べ、そうでなければ後半を調べます。目的のアイテムが見つかるまでこれを繰り返します。テーブルはバイナリ検索用にソートする必要があります。各反復で半分のデータを削除します。対数です。

検索する要素が1000個ある場合、バイナリ検索には約10ステップ、線形検索には1000ステップかかります。

2
Prabhu. S

明確な理解のために、私のcodepen実装を見てください https://codepen.io/serdarsenay/pen/XELWqN

最大の違いは、バイナリ検索を適用する前にサンプルをソートする必要があることです。したがって、ほとんどの「通常サイズ」(議論されることを意味します)では、線形検索アルゴリズムを使用したサンプルの検索が速くなります。

ここにjavascriptコードがあります。htmlとcssおよび完全な実行例については、上記のcodepenリンクを参照してください。

var unsortedhaystack = [];
var haystack = [];
function init() {
  unsortedhaystack = document.getElementById("haystack").value.split(' ');
}
function sortHaystack() {
  var t = timer('sort benchmark');
  haystack = unsortedhaystack.sort();
  t.stop();
}

var timer = function(name) {
    var start = new Date();
    return {
        stop: function() {
            var end  = new Date();
            var time = end.getTime() - start.getTime();
            console.log('Timer:', name, 'finished in', time, 'ms');
        }
    }
};

function lineerSearch() {
  init();
  var t = timer('lineerSearch benchmark');
  var input = this.event.target.value;
  for(var i = 0;i<unsortedhaystack.length - 1;i++) {
    if (unsortedhaystack[i] === input) {
      document.getElementById('result').innerHTML = 'result is... "' + unsortedhaystack[i] + '", on index: ' + i + ' of the unsorted array. Found' + ' within ' + i + ' iterations';
      console.log(document.getElementById('result').innerHTML);
      t.stop(); 
      return unsortedhaystack[i]; 
    }
  }
}

function binarySearch () {
  init();
  sortHaystack();
  var t = timer('binarySearch benchmark');
  var firstIndex = 0;
  var lastIndex = haystack.length-1;
  var input = this.event.target.value;

  //currently point in the half of the array
  var currentIndex = (haystack.length-1)/2 | 0;
  var iterations = 0;

  while (firstIndex <= lastIndex) {
    currentIndex = (firstIndex + lastIndex)/2 | 0;
    iterations++;
    if (haystack[currentIndex]  < input) {
      firstIndex = currentIndex + 1;
      //console.log(currentIndex + " added, fI:"+firstIndex+", lI: "+lastIndex);
    } else if (haystack[currentIndex] > input) {
      lastIndex = currentIndex - 1;
      //console.log(currentIndex + " substracted, fI:"+firstIndex+", lI: "+lastIndex);
    } else {
      document.getElementById('result').innerHTML = 'result is... "' + haystack[currentIndex] + '", on index: ' + currentIndex + ' of the sorted array. Found' + ' within ' + iterations + ' iterations';
      console.log(document.getElementById('result').innerHTML);
      t.stop(); 
      return true;
    }
  }
}
0
serdarsenay

Linear Searchは、検索された値が見つかるまでアイテムを調べます。

効率:O(n)

例Pythonコード:

test_list = [1, 3, 9, 11, 15, 19, 29]
test_val1 = 25
test_val2 = 15

def linear_search(input_array, search_value):
    index = 0
    while (index < len(input_array)) and (input_array[index] < search_value):
        index += 1
    if index >= len(input_array) or input_array[index] != search_value:
        return -1

    return index


print linear_search(test_list, test_val1)
print linear_search(test_list, test_val2)

Binary Searchは、配列の中央の要素を見つけます。中央の値が検索値よりも大きいか小さいかを確認します。小さい場合、配列の左側を取得し、その部分の中央の要素を見つけます。大きい場合、配列の正しい部分を取得します。検索された値が見つかるまで、操作をループします。または、配列に値がない場合は検索を終了します。

効率:O(logn)

例Pythonコード:

test_list = [1, 3, 9, 11, 15, 19, 29]
test_val1 = 25
test_val2 = 15

def binary_search(input_array, value):
    low = 0
    high = len(input_array) - 1
    while low <= high:
        mid = (low + high) / 2
        if input_array[mid] == value:
            return mid
        Elif input_array[mid] < value:
            low = mid + 1
        else:
            high = mid - 1

    return -1


print binary_search(test_list, test_val1)
print binary_search(test_list, test_val2)

また、ここで線形検索とバイナリ検索に関する視覚化された情報を見ることができます: https://www.cs.usfca.edu/~galles/visualization/Search.html

0
Can Uludağ