バイナリ検索を使用して要素の配列を検索するには、最悪の場合、回の反復が必要です。これは、各ステップで検索スペースの半分をトリミングするためです。代わりに、「三分探索」を使用した場合、各反復で探索空間の3分の2を切り捨てるので、最悪の場合は反復が必要です...log 2 N log 3 N < log 2 N
三項検索の方が速いように思えますが、なぜ二項検索を使用するのですか?
バイナリ検索を使用して要素の配列を検索するには、最悪の場合、回の反復が必要です。これは、各ステップで検索スペースの半分をトリミングするためです。代わりに、「三分探索」を使用した場合、各反復で探索空間の3分の2を切り捨てるので、最悪の場合は反復が必要です...log 2 N log 3 N < log 2 N
三項検索の方が速いように思えますが、なぜ二項検索を使用するのですか?
回答:
バイナリ検索を適用すると、多くの比較があります。三項検索を適用すると、多くの比較があります。各ステップで、検索スペースを3つの部分に分割するために2つの比較を実行する必要があります。計算すると、次のことがます 我々は知っているので、その、我々は実際に得るより 3分探索との比較を。
ちなみに、検索は、比較に非常にコストがかかり、並列コンピュータを適用できる場合に並列化できる場合に非常に意味があります。
引数は検索に簡単に一般化できることに注意してください。関数が整数値に対して厳密に単調増加することを示す必要があります。F (K )= (K - 1 )⋅ ログ(2 ) k
DCTLibは正しいですが、数学をちょっと忘れてください。
あなたのロジックでは、n- aryが最も速いはずです。ただし、考えてみると、n -aryは通常の反復検索とまったく同じです(リストを1つずつ反復しますが、逆順です)。まず、リスト内の最後の(または最後から2番目の)アイテムを選択し、その値を比較値と比較します。次に、そのアイテムをリストから削除し、新しいリストの最後のアイテムを選択します。これは、配列の最後の値の直後にあります。毎回、値が見つかるまで一度に1つの値のみを削除します。
代わりに、このように考える必要があります-反復ごとにリストからほとんどの値を削除する方法は?バイナリ検索では、常にリストの半分を削除します。3項検索では、リストの2/3を削除できる可能性(実際には33.33%の可能性)がありますが、リストの1/3のみを削除する可能性はさらに大きくなります(66.66%)。O(n)を計算するには、最悪のシナリオ、つまり1 / 3、1 / 2未満を調べる必要があります。nに近づくにつれて、さらに悪化します。
バイナリ検索で最悪のシナリオが改善されるだけでなく、平均時間も改善されます。期待値(リストのどの部分を平均して削除できるか)を見て、次の式を使用します。
(P_lower)x(低い場合は削除できる部分)+(P_higher)x(高い場合は削除できる部分)= E
バイナリ検索の場合、これは.5x.5 + .5x.5 = .5です(リストの半分は常に削除されます)。三項検索の場合、この値は.666x.333 + .333x.666 = 0.44であるか、各ステップでリストの44%のみを削除する可能性が高く、平均して二分検索よりも効率が低下します。この値は1/2(リストの半分)でピークに達し、n(逆反復)と0(通常反復)に近づくほど減少します。
わかりましたので、私は嘘をついた..少し数学が関与しているが、私はそれが役立つことを願っています!
log(N)対2 log(N)比較引数は、アルゴリズムの単純な解釈に基づいていることに注意してください。実際に座ってx86アセンブリでこれを記述すると、結果は逆になります。問題は、冗長な比較を削除できない不十分なスマートコンパイラと組み合わされたテストケースの整数の使用です。文字列と適切な文字列比較関数を使用して再試行し、ループごとに1回比較関数を呼び出すようにコーディングすると、3項検索が再び高速になります。