web-dev-qa-db-ja.com

バイナリ検索の複雑さを計算する方法

バイナリ検索は検索に必要な入力を半分にするので、log(n)アルゴリズムだと誰かが言うのを聞きました。私は数学のバックグラウンドではないので、それに関係することはできません。誰かがそれをもう少し詳しく説明できますか?対数系列で何かをする必要がありますか?

128
Bunny Rabbit

ここでは、数学的な見方を示しますが、実際には複雑ではありません。 IMOは非公式なものとしてより明確です:

問題は、1になるまでNを2で除算できる回数です。これは本質的に、あなたがそれを見つけるまでバイナリ検索(要素の半分)を行うことを言っています。数式では、これは次のようになります。

1 = N/2バツ

2を掛けるバツ

2バツ = N

今ログをする2

ログ2(2バツ)=ログ2 N
x *ログ2(2)=ログ2 N
x * 1 =ログ2 N

つまり、すべてが分割されるまで、ログをN回分割できます。つまり、要素が見つかるまで、ログNを分割する必要があります(「バイナリ検索ステップを実行」)。

352
duedl0r

バイナリ検索の場合、T(N) = T(N/2) + O(1) //再帰関係

繰り返し関係の実行時の複雑さを計算するためのマスター定理の適用:T(N) = aT(N/b)+ f(N)

ここで、a = 1、b = 2 => log(a base b)= 1

また、ここf(N) = n ^ c log ^ k(n)// k = 0&c = log(a base b)

したがって、T(N) = O(N ^ c log ^(k + 1)N)= O(log(N))

ソース: http://en.wikipedia.org/wiki/Master_theorem

19
Karshit

T(n)= T(n/2)+1

T(n/2)= T(n/4)+ 1 + 1

T(n)= T(n/4)+ 1 + 1になるように、上記にThe(n/2)の値を入れます。 。 。 。 T(n/2 ^ k)+ 1 + 1 + 1 ..... + 1

= T(2 ^ k/2 ^ k)+ 1 + 1 .... + 1 kまで

= T(1)+ k

2 ^ k = nを取ったとき

K = log n

時間の複雑さはO(log n)です

15
Dhiren Biren

検索時間が半分にならないため、log(n)にはなりません。対数的に減少します。これについて少し考えてみてください。テーブルに128個のエントリがあり、値を直線的に検索する必要がある場合、おそらく値を見つけるには平均で約64個のエントリが必要です。それはn/2または線形時間です。バイナリ検索では、反復ごとに1/2の可能性のあるエントリを削除し、値を見つけるのに最大で7回しか比較しないようにします(128の対数2は7または2の7乗は128です)。バイナリ検索の力。

10
Michael Dorgan

バイナリ検索アルゴリズムの時間の複雑さは、O(log n)クラスに属します。これは big O notation と呼ばれます。これを解釈する方法は、サイズnの入力セットが与えられた場合に関数の実行に要する時間の漸近的な増加がlog nを超えないことです。

これは、ステートメントなどを証明できるようにするための正式な数学的専門用語です。非常に簡単な説明があります。 nが非常に大きくなると、log n関数は関数の実行に要する時間を超えて成長します。 「入力セット」のサイズnは、リストの長さです。

簡単に言えば、バイナリ検索がO(log n)にある理由は、各反復で入力セットを半分にするためです。逆の状況で考えるのは簡単です。 x回の繰り返しで、最大でバイナリ検索アルゴリズムが検査できるリストの長さはどれくらいですか?答えは2 ^ xです。このことから、逆に、平均して、バイナリ検索アルゴリズムは長さnのリストに対してlog2 n回の反復を必要とすることがわかります。

なぜO(log n)ではなくO(log n)なのかというと、単純に再び配置するためです-大きなO表記定数を使用してもカウントされません。

5
vidstige

Log2(n)は、バイナリ検索で何かを見つけるために必要な検索の最大数です。平均的なケースには、log2(n)-1検索が含まれます。詳細は次のとおりです。

http://en.wikipedia.org/wiki/Binary_search#Performance

3
Jonathan M

wikipedia エントリです

単純な反復アプローチを見ると。必要な要素が見つかるまで、検索対象の要素の半分を削除するだけです。

ここで、この公式をどのように考案するかについて説明します。

最初にN個の要素があり、最初の試行として⌊N/2⌋を実行するとします。 Nは、下限と上限の合計です。 Nの最初の値は(L + H)に等しくなります。Lは最初のインデックス(0)で、Hは検索するリストの最後のインデックスです。運がよければ、見つけようとしている要素は真ん中にあります。リスト{18、17、18、19、20}で18を検索し、you(0 + 4)/2⌋= 2を計算します。0は下限(L-配列の最初の要素のインデックス) 4は上限です(H-配列の最後の要素のインデックス)。上記の場合、L = 0およびH = 4です。2は、検索中の要素18のインデックスです。ビンゴ!あなたは見つけた。

ケースが別の配列{15,16,17,18,19}であるが、まだ18を検索している場合、ラッキーではなく、最初のN/2を実行します(which(0 + 4)/ 2⌋= 2で、インデックス2の要素17が探している数字ではないことに気付きます。これで、次の反復方法の検索で、配列の少なくとも半分を探す必要がないことがわかります。したがって、基本的には、以前の試行で見つけることができなかった要素を見つけようとするたびに、以前に検索した要素のリストの半分を検索しません。

最悪の場合は

[N]/2 + [(N/2)]/2 + [((N/2)/ 2)]/2 .....
i.e:
N/21 + N/22 + N/23 + ..... + N/2バツ …..

…検索が終了するまで、検索しようとしている要素のどこがリストの最後にあるか。

最悪の場合は、N/2に達したときです。バツ ここで、xは2バツ = N

その他の場合N/2バツ ここで、xは2バツ <N xの最小値は1で、これが最良のケースです。

数学的に最悪の場合は、
2バツ = N
=>ログ2(2バツ)=ログ2(N)
=> x *ログ2(2)=ログ2(N)
=> x * 1 =ログ2(N)
=>より正式なログ2(N)+1⌋

3
RajKon

リストを毎回半分に削減するため、リストを2で除算するときに1を得るステップ数を知る必要があります。下の計算では、xは、1つの要素を取得するまでリストを分割する回数を示します(最悪の場合)。

1 = N/2x

2x = N

Log2を取る

log2(2x)= log2(N)

x * log2(2)= log2(N)

x = log2(N)

1
Abdul Malik

T(N)= T(N/2) + 1

T(N)= T(N/2) + 1 =(T(N/4)+ 1)+ 1

...

T(N)= T(N/N) +(1 + 1 + 1 + ... + 1)= 1 + logN(2を底とする対数)= 1 + logN

したがって、バイナリ検索の時間の複雑さはO(logN)です

1
TizeeU0U

バイナリ検索は、問題を次のように繰り返し半分に分割することで機能します(詳細は省略)。

[4,1,3,8,5]で3を探す例

  1. アイテムのリストを注文[1,3,4,5,8]
  2. 中央の項目(4)を見てください。
    • 探しているものなら、やめて
    • 大きい場合は、前半を見てください
    • 少ない場合は、後半を見てください
  3. 新しいリスト[1、3]でステップ2を繰り返し、3を見つけて停止します

問題を2に分割すると、bi-nary検索になります。

検索では、正しい値を見つけるためにlog2(n)ステップのみが必要です。

アルゴリズムの複雑さについて学びたい場合は、 Introduction to Algorithms をお勧めします。

1
Silas Parker
ok see this
for(i=0;i<n;n=n/2)
{
i++;
}
1. Suppose at i=k the loop terminate. i.e. the loop execute k times.

2. at each iteration n is divided by half.

2.a n=n/2                   .... AT I=1
2.b n=(n/2)/2=n/(2^2)
2.c n=((n/2)/2)/2=n/(2^3)....... aT I=3
2.d n=(((n/2)/2)/2)/2=n/(2^4)

So at i=k , n=1 which is obtain by dividing n  2^k times
n=2^k
1=n/2^k 
k=log(N)  //base 2
0
Piyush Jain

バイナリ検索の反復がk回の反復後に終了するとします。各反復で、配列は半分に分割されます。したがって、反復での配列の長さはn It Iteration 1であるとします

Length of array = n

反復2で

Length of array = n⁄2

反復3で

Length of array = (n⁄2)⁄2 = n⁄22

したがって、反復kの後、

Length of array = n⁄2k

また、k分割後、配列の長さが1になるしたがって、

Length of array = n⁄2k = 1
=> n = 2k

両側にログ機能を適用する:

=> log2 (n) = log2 (2k)
=> log2 (n) = k log2 (2)
As (loga (a) = 1)

したがって、

As (loga (a) = 1)
k = log2 (n)

したがって、バイナリ検索の時間の複雑さは

log2 (n)
0
SirPhemmiey

例を挙げて、すべての人が簡単にできるようにしましょう。

簡単にするために、バイナリ検索を使用して要素を検索している並べ替えられた順序で配列に32個の要素があると仮定します。

1 2 3 4 5 6 ... 32

32を検索していると仮定します。最初の反復の後、

17 18 19 20 .... 32

2回目の反復の後、

25 26 27 28 .... 32

3回目の反復の後、

29 30 31 32

4回目の反復の後、

31 32

5回目の反復では、値32が見つかります。

したがって、これを数学の方程式に変換すると、次のようになります。

(32 X(1/25))= 1

=> n X(2-k)= 1

=>(2k)= n

=> k log22 =ログ2n

=> k =ログ2n

したがって、証拠。

0
Sumukha H S