編集 これは受け入れられているので、本当に正しい答えに変えようとする必要があると思います。
私は当初、質問がハーフオープン境界を使用していると想定していました (以下の「注」以降を参照)。実際には(正しく)包括的境界を使用しています。最初の呼び出しで、low=0
およびhigh=n-1
.
包括的境界を使用することは、しばしば悪いことと見なされます。Dijkstra の古典的な記事 (PDF) を参照してください。C ファミリ言語では、ハーフ オープン境界が一般的な規則であり、for (i = 0; i < n; i++)
overが優先されfor (i = 0; i <= n-1; i++)
ます。ただし、包括的な境界が使用されていることを考えると、問題のコードは正しいようです。
ただし、コメントで WhozCraig が発見したように、呼び出し元のコードはその規則を尊重しておらず、間違った境界を渡していました。検索範囲に境界外のガベージ アイテムが含まれていました。その余分なアイテムはガベージであるため、範囲内のアイテムがソートされているという仮定も無効になる可能性があります。ほとんどの検索では、そのごみアイテムは見つかりません (ごみの価値があるものを検索する可能性は低いため) が、検索の方向を誤ってしまいます。
注 これはおそらく答えではありませんが、コメントするには長すぎます。
あなたの境界は包括的、排他的、または半分開いていますか?
で半開low
、排他でを仮定しhigh
ます。もしそうなら、この行は間違っているように見えます...
if (target < * (oringalary + mid))
return recurbinarysearch(oringalary, low, mid - 1, target);
理由は、アイテムを で確認しましたが、新しい排他的上限としてmid
を使用しているためです。これは、チェックされていない のアイテムが誤って検索から除外されたことを意味します。ラインは...mid - 1
mid - 1
if (target < * (oringalary + mid))
return recurbinarysearch(oringalary, low, mid, target);
これにより、アイテムmid - 1
が検索範囲内に保持されます。mid
上限が排他的であるため、のアイテムは再度検索されません。
二分探索で境界を台無しにすることは一般的な問題であり、見た目よりも多くのエラーが発生します。
ただし、これだけではあなたの症状を説明することはできません -時々 (おそらく検索の約 50%)アイテムを見つけられないはずですが、成功した検索の間違った位置を報告するべきではありません.
二分探索で境界が間違っている場合の通常の症状は、無限ループ (境界から除外されていないために同じ項目が繰り返しチェックされる) または存在する項目を検索で見つけられない (項目が検索範囲から除外されたため) です。チェックされていません)。
正直なところ、あなたの症状がどのように発生するのかわかりません。関数が終了する可能性のあるすべての方法で、正しい成功の結果が得られるか、-1
失敗の結果が得られる必要があります。私が考えることができる唯一の例外は、このコードの外側にあります。たとえば、-1
結果のチェックに失敗するなど、結果を誤って解釈することです。
ところで-これは、反復ごとに1回の比較のバイナリ検索について、私の質問と回答を売春婦に説明する絶好の機会です。
編集境界に別の問題を見つけたと思います-まだ半分開いていると仮定すると、この行は間違っています...
if (low > high) {
そしてあるべき...
if (low >= high) {
その理由は、半分開いた境界の場合、境界が等しい場合、その間にチェックする項目がないためです。上限がそれと等しく、排他的であるため、下限の項目でさえ有効ではありません。これにより、引き続きテストできます