web-dev-qa-db-ja.com

バイナリ検索を使用した挿入ソート

挿入ソートを実装する場合、バイナリ検索を使用して、要素iを挿入する配列の最初のi-1要素内の位置を見つけることができます。

これは必要な比較の数にどのように影響しますか?このようなバイナリ検索を使用すると、挿入ソートの漸近的な実行時間にどのような影響がありますか?

これにより比較の数が減ると確信していますが、その理由は正確にはわかりません。

15
Derrek Whistle

ウィキペディアから直接:

比較のコストがスワップのコストを超える場合、たとえば、参照によって保存された文字列キーや人間の操作(並べて表示されたペアの1つを選択するなど)の場合と同様に、バイナリ挿入ソートを使用すると、よりよい性能。 バイナリ挿入ソートは、バイナリ検索を使用して新しい要素を挿入するための正しい場所を決定するため、最悪の場合、O(n log n)で「log2(n)」比較を実行します)。アルゴリズム全体としては、各挿入に一連のスワップが必要なため、実行時間は平均してO(n2))です。

ソース:

http://en.wikipedia.org/wiki/Insertion_sort#Variants

次に例を示します。

http://jeffreystedfast.blogspot.com/2007/02/binary-insertion-sort.html

これにより比較の数が減ると確信していますしかし、その理由は正確にはわかりません。

まあ、もしあなたがすでに挿入ソートと二分探索を知っているなら、それはかなり簡単です。挿入ソートでピースを挿入する場合、以前のすべてのピースと比較する必要があります。これ[2]を正しい場所に移動したいとします。正しい場所を見つける前に、7個と比較する必要があります。

[1] [3] [3] [3] [4] [4] [5]->[2]<-[11] [0] [50] [47]

ただし、(バイナリ検索のように)中間点で比較を開始すると、比較できるのは4個のみになります。これができるのは、左側のピースがすでに順序付けられていることがわかっているためです(ピースが順序付けられている場合にのみバイナリ検索を実行できます!)。

ここで、数千(または数百万)のピースがある場合、これにより多くの時間を節約できると想像してください。これがお役に立てば幸いです。 | = ^)

効率的なバイナリ検索のための適切なデータ構造がある場合、O(log n)挿入時間はありそうにありません。逆に、任意の位置に高速挿入するための適切なデータ構造は、バイナリ検索をサポートする可能性は低いです。

挿入ソートによる最良の比較検索のO(n log n)パフォーマンスを実現するには、O(log n)バイナリ検索とO(log n)任意挿入の両方が必要です。

6

配列が(バイナリ検索を実行するために)ソートされていると仮定すると、内部ループは1つの比較の直後に終了するため(前の要素が小さいため)、比較は減りません。一般に、挿入ソートでの比較の数は、最大で反転の数に配列サイズを加えたものです-1。

ソートされた配列の反転の数は0であるため、すでにソートされた配列の比較の最大数はN-1です。

1
WastedPandoo

バイナリ挿入ソート-この配列を取る=> {4、5、3、2、1}

ここで、メインループ内で、3番目の要素にいるとします。これで、バイナリ検索を使用して、3を挿入する場所、つまり4の前に挿入する場所がわかります。

バイナリ検索ではO(Logn)比較を使用しますが、これは改善ですが、適切な場所に3を挿入する必要があります。そのためには、3を5に、次に4に交換する必要があります。

挿入に時間がかかるため、バイナリ検索を行わない場合と同じ時間がかかるため、最悪の場合の複雑性はO(n ^ 2)のままです。これがお役に立てば幸いです。

1
Armaan Chugh