web-dev-qa-db-ja.com

ソートされたデータを必要とするバイナリ検索が線形検索よりも優れていると考えられるのはなぜですか?

線形検索は素朴なアプローチであり、バイナリ検索は漸近的な複雑さによりパフォーマンスが優れているといつも聞いていました。しかし、バイナリ検索の前にソートが必要な場合、なぜ線形検索より優れているのか理解できませんでしたか?

線形検索はO(n)であり、バイナリ検索はO(log n)です。これは、バイナリ検索の方が優れているという根拠のようです。しかし、二分探索は、最良のアルゴリズムのためにO(n log n)であるソートを必要とします。したがって、バイナリ検索は実際には高速ではないはずですasソートが必要です。

私はCLRSを読んでいます。著者は、単純な線形検索アプローチを使用する代わりに挿入ソートでは、アイテムを挿入する必要がある場所を見つけるためにバイナリ検索を使用する方がよいと示唆しています。この場合、各ループの繰り返しで、バイナリ検索を適用できるソートされたリストがあるため、これは正当化されるようです。しかし、検索する必要のあるデータセットがバイナリ検索を使用していないという一般的なケースでは、並べ替えの要件により、実際には線形検索よりも性能が悪いのでしょうか。

線形検索よりもバイナリ検索の方が優れている、見落としている実用的な考慮事項はありますか?または、ソートに必要な計算時間を考慮せずに、バイナリ検索は線形検索よりも優れていると考えられますか?

20
Aseem Bansal

私が見落としている、線形検索よりもバイナリ検索の方が優れている実用的な考慮事項はありますか?

はい-O(n log n)ソートを1回だけ実行する必要があります。その後、O(log n)バイナリ検索を必要なだけ実行できますが、線形検索はO(n)です。毎回。

もちろん、これは実際に同じデータに対して複数の検索を実行する場合にのみ利点です。ただし、「1回書き込み、頻繁に読み取る」シナリオは非常に一般的です。

53

基本的な前提は、1つの検索を行わないことです。

したがって、同じデータを複数回検索する必要がある場合は、ソートを1回行うだけで済み、バイナリ検索を利用できます。

検索を頻繁に行い、データが変化する場合は、新しいエントリがリストにソートされるソートリストを使用することをお勧めします。

そのため、基本的にバイナリ検索は、同じリストを何度も検索する場合に、手段をとる必要なしに優れています。

検索する前に毎回ソートする必要がある場合、利点はありません。

リストが既に並べ替えられている(または並べ替えがほぼ完了している)場合に非常に高速な並べ替えアルゴリズムがあることにご注意ください。ほとんどのパフォーマンス決定は、ソートされていないリストを想定しています。

14
Uwe Plonus

並べ替えられたリストがあれば、毎回並べ替える必要がないため、O(log n)を超える検索がある場合、事前に並べ替えることで利益を得ることができます(O(n log n + k log n) vs O(k*n)

7
ratchet freak

2つの電話帳を想像してみてください。

1つの電話帳には、アルファベット順に名前が付いています。目的のエントリを見つけるには、中央を開いてエントリを確認し、オーバーシュートまたはアンダーシュートに応じて前後に移動します。

他の電話帳には、ランダムな順序で名前があります。必要なエントリを見つけるには、最初から始めて、必要なものが見つかるまで続けます。

2冊目の本は、適度なサイズの都市で機能しますか?

5
Gort the Robot

線形検索よりもバイナリ検索の方が価値があると思います。膨大な順序付けされていないデータセットから始めて、そこから少数の項目を抽出することを計画している場合、バイナリ検索のソートと実行は遅くなります。ただし、アプリケーションの存続期間を通じて順序付きリストを維持し、定期的にアクセスする場合は、バイナリ検索の方がはるかに優れています。

3

他の多くの人が回答したように、並べ替え手順は1回しか実行できず、実際の検索は何回でも実行できるため、バイナリ検索が実際に望ましい方法です。ただし、nの特定の値(つまり、特定の入力サイズ)の場合、バイナリ検索はalways線形検索よりもパフォーマンスが高くなります( 1回の実行の場合)。

「転換点」は、漸近的な複雑さの方程式を解くことによって計算されます。

n log n + log n = n

できる限り Wolfram Alphaを参照nには数値があります。これにより、バイナリ検索と並べ替えが線形検索のみよりも常に高速になります。もちろん、あなたのケースで機能するnactual値は、推定するのが難しい多くの要因に依存します。

マークプロブストによる この興味深い記事 によると、現在のプロセッサでのいくつかのナイスインデプスパフォーマンス測定が含まれています。

並べ替えられた整数の配列を検索する必要があり、パフォーマンスが本当に重要な場合、配列のサイズが約64要素以下の場合は線形検索を使用し、それ以上の場合はバイナリ検索を使用します。

3
LorenzCK

素人の言葉で:

100億個のアイテムを含む順序付けられていないリストがあり、たまたま探しているアイテムが最後のリストである場合、100億個のアイテムを読み取ることになります。

二分探索の場合、索引付けは一度だけ行うことができます。後で挿入を正しい場所に行って、順序を維持できます。

2

「バイナリ検索の方が良い」という多くの正当な理由がすでにリストされていますが、ユーザーの観点からも利点を確認することができます。

通常、ソートされた挿入を実行するときのデータ入力アクション間での小さな待機時間の分割で非常にうまく生きることができますが、「検索」を可能な限り高速にする必要があります。ユーザーの観点から見ると、ソートされた挿入とバイナリ検索を組み合わせると、可能な限り最高のユーザーエクスペリエンスが得られます。

2
tofro