マージソートの「分割」ステップを回避できますか?


13

ソートをマージ

したがって、マージソートは、分割統治アルゴリズムです。上記の図を見ながら、基本的にすべての分割ステップをバイパスできるかどうか考えていました。

2つずつジャンプしながら元の配列を反復処理した場合、インデックスiおよびi + 1の要素を取得し、独自のソートされた配列に入れることができます。これらのすべてのサブ配列(図に示すように[7,14]、[3,12]、[9,11]および[2,6])を取得したら、通常のマージルーチンに進んで取得します。ソートされた配列。

配列を繰り返し処理し、必要なサブ配列をすぐに生成するのは、分割ステップを全体で実行するよりも効率が悪いですか?


回答:


29

混乱は、アルゴリズムの概念的な記述とその実装の違いから生じます

論理的にマージソートは、配列をより小さな配列に分割し、それらを再び結合することとして説明されています。ただし、「配列の分割」は、「メモリ内にまったく新しい配列を作成する」などを意味するものではありません。コード内で次のように実装できます。

/*
 * Note: array is now split into  [0..n) and [n..N)
 */

つまり、実際の作業は行われず、「分割」は純粋に概念的なものです。したがって、あなたが提案することは確かに動作しますが、論理的にはまだアレイを「分割」しています-そうするためにコンピュータからの作業は必要ありません:-)


4
個人的には、ボトムアップマージソートが本当に好きです。なぜなら、各再帰レベルで一時バッファーを割り当てないように実装する方が簡単だからです。代わりに、バッファを1回割り当て、それらの間でピンポンを行います。
ラチェットフリーク

これ-除算は計算上無操作です... OPの提案は、単一要素配列のマージに相当するものの紹介であり、元のマージも同様に機能するため、第2ステップからのマージの使用は冗長と思われます。それを最適化する意味はありません。冗長な概念とロジックのみを紹介します。
luk32

@ratchetfreak:私も大好きですが、残念ながらトップダウン(少なくとも私が知っているバージョン)とは異なります。基本的に次の2のべき乗の配列の長さに切り上げますが、少し遅くなると思います。他のどこかで多額の費用を支払うことなく、まったく同じマージを行うボトムアップバージョンを知っていますか?
user541686

@Mehrdadの唯一の実際の問題は、マージする必要がある小さなテールです。最悪の場合、長さの配列の単一のアイテムにマージする別のパスを意味します1<<n+1。私はあなたが物事を調整することができると確信しているので、小さすぎるテールは低域でマージされます。
ラチェットフリーク

@psmears「これを行うのにコンピュータの作業は必要ありません」-したがって、いくつかの再帰的な除算関数のn回の呼び出し(図の例では7回の呼び出し)のパフォーマンスコストは基本的に無視できると思いますか?
-Jimmy_Rustle

11

あなたが言っているのはボトムアップの実装だと思います。ボトムアップ実装では、単一のセル要素から開始し、要素をより大きなソートされたリスト/配列にマージすることにより、上に移動します。上の図の矢印を、真ん中の配列、つまり1要素の配列から始めて逆にします。

また、一定のサイズに達するまで配列を分割することでマージソート最適化し、その後、挿入ソートなどを使用して単純にソートすることもできます。

そうでない場合、配列を分割せずにソートすることはできません。実際、マージソートの要点は、サブアレイの分割とソート、つまり分割統治です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.