回答:
実際には複雑ではありませんが、これをより数学的な方法で確認します。IMOは非公式のものとしてより明確です:
問題は、1になるまでNを2で割ることができる回数です。これは本質的に言って、あなたがそれを見つけるまで二分探索(要素の半分)をしてください。数式では、これは次のようになります。
1 = N / 2 x
2 xを掛ける:
2 x = N
ログ2を実行します。
log 2(2 x)= log 2 N
x * log 2(2)= log 2 N
x * 1 = log 2 N
これは、すべてを分割するまでログをN回分割できることを意味します。つまり、要素が見つかるまでログNを分割する(「バイナリ検索ステップを実行する」)必要があります。
二分探索の場合、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底b)
したがって、T(N)= O(N ^ c log ^(k + 1)N)= O(log(N))
検索時間の半分ではないため、log(n)にはなりません。対数的に減少します。これについて少し考えてみましょう。テーブルに128のエントリがあり、直線的に値を検索する必要がある場合、値を見つけるには平均で約64のエントリが必要になります。それはn / 2または線形時間です。バイナリ検索を使用すると、反復ごとに可能なエントリの1/2を排除するため、最大7回の比較で値を見つけることができます(128の対数2は7または2の7乗は128です)。これはバイナリサーチの力。
二分探索アルゴリズムの時間の複雑さは、O(log n)クラスに属します。これは、ビッグO表記と呼ばれます。これを解釈する方法は、サイズnの入力セットが与えられた場合、関数の実行にかかる時間の漸近的な増加はを超えないことlog n
です。
これは、ステートメントなどを証明できるようにするための正式な数学的用語です。非常に簡単な説明があります。nが非常に大きくなると、log n関数は、関数の実行にかかる時間より長くなります。「入力セット」のサイズnは、リストの長さです。
簡単に言うと、バイナリ検索がO(log n)にあるのは、反復ごとに入力セットが半分になるためです。逆の状況で考える方が簡単です。x回の反復で、バイナリ検索アルゴリズムが最大でリストをどのくらい長く検査できるか?答えは2 ^ xです。このことから、逆は、長さnのリストに対して、バイナリ検索アルゴリズムが平均してlog2 n回の反復を必要とすることがわかります。
なぜO(log n)であり、O(log2 n)ではないのかというと、単純に言えば、大きなO表記定数を使用しても意味がありません。
ここにウィキペディアのエントリがあります
単純な反復アプローチを見てください。必要な要素が見つかるまで、検索する要素の半分を削除するだけです。
ここでは、数式を作成する方法について説明します。
最初にN個の要素があるとします。次に、最初の試みとして「N / 2」を実行します。ここで、Nは下限と上限の合計です。Nの最初の値は(L + H)に等しくなります。Lは検索するリストの最初のインデックス(0)で、Hは最後のインデックスです。運が良ければ、見つけようとする要素は真ん中になるでしょう[eg。リスト{16、17、18、19、20}で18を検索し、⌊(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 .....
つまり、
N / 2 1 + N / 2 2 + N / 2 3 + ..... + N / 2 x …..
…検索が終了するまで、検索しようとしている要素がリストの最後にあります。
これは、 xが2 x = NであるようなN / 2 xに到達したときが最悪のケースであることを示しています。
他のケースでは、N / 2 xです。 ここで、xは2 x <Nのようなものです。xの最小値は1になる可能性があり、これが最良のケースです。
数学的に最悪の場合は
2 x = N
=> log 2(2 x)= log 2(N)
=> x * log 2(2)= log 2(N)
=> x * 1 = log 2(N)
=>より正式⌊log 2(N)+1⌋
Log2(n)は、バイナリ検索で何かを見つけるために必要な検索の最大数です。平均的なケースには、log2(n)-1検索が含まれます。詳細は次のとおりです。
Binary Searchの反復がk回の反復後に終了するとします。各反復で、配列は半分に分割されます。したがって、任意の反復での配列の長さがnであるとします。反復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)
二分探索は、このような問題を繰り返し半分に分割することで機能します(詳細は省略)。
[4,1,3,8,5]で3を探す例
問題を2つに分割すると、2項検索になります。
検索では、正しい値を見つけるためにlog2(n)ステップのみが必要です。
アルゴリズムの複雑さについて学びたい場合は、アルゴリズム入門をお勧めします。
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
皆さんのために、例を挙げて簡単にします。
簡単にするために、配列に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/2 5))= 1
=> n X(2 -k)= 1
=>(2 k)= n
=> k log 2 2 = log 2 n
=> k = log 2 n
したがって、証拠。