小さな要素のリストに対して、挿入がソートの方がクイックソートよりも優れているのはなぜですか?

Isnt Insertion sort O(n^2) > Quick sort O(nlogn)...so for a small n, wont the relation be the same?

18
追加された 編集された
ビュー: 1

5 答え

Big-O Notationは、nが大きいときの漸近挙動として知られる制限動作を記述する。これは近似値です。 ( http://ja.wikipedia.org/wiki/Big_O_notation を参照)

クイックソートは再帰関数呼び出しの余分なオーバーヘッドがあるため、小さなソートの場合は挿入ソートが高速です。挿入ソートは、クイックソートよりも安定しており、メモリが少なくて済みます。

この質問は、挿入ソートのいくつかのさらなる利点について説明しています。 (挿入ソートを使用する理由はありますか?

19
追加された
申し訳ありませんが、私はクイックソートはより多くのメモリを必要とは思わない。この答えは間違っています。
追加された 著者 SmallChess,
@SmallChess、そうだよ。一度にlogN個の再帰スタックが必要になります。
追加された 著者 Oorja,

「小さい」を定義します。

ソートアルゴリズムをベンチマークするとき、quicksortから挿入ソートに切り替えると、実際には4つ以上の要素の配列のパフォーマンス(Cの再帰的クイックソート)が損なわれることがわかりました。これらの配列は、サイズに依存する最適なソートアルゴリズムでソートすることができます。

つまり、 O(n ...)はアルゴリズムの速度ではなく、(この具体例では)比較の回数だけであることに注意してください。速度は実装に依存します。たとえば、クイックソートが再帰的に機能するかどうか、関数呼び出しがどれだけ迅速に処理されるかなどです。

最後の重要なことに、大きな表記は唯一の上限です。

アルゴリズムAが 10000 n log n の比較を必要とし、アルゴリズムBが 10 n ^ 2 を必要とする場合、最初は O(n log n) 2番目は O(n ^ 2)です。それにもかかわらず、2番目は(おそらく)速くなるでしょう。

10
追加された
興味深いことに、 N = 9000 になるまで、 O(N ^ 2)O(N Log N)エントリなどです。
追加された 著者 sarnold,
@Dennis: Wolfram Alphaをチェックしてください。または echo "10000 * 9000 * l(9000); 10 * 9000 * 9000" | bc -l <�​​/ code>。
追加された 著者 sarnold,
@Dennis:不思議ではない! :)コメントでさえそれが正確であるのに役立つもう一つの思い出を...
追加された 著者 sarnold,
@sarnold:それは 20,000,000100,000 の比較です。とんでもない。
追加された 著者 Dennis,
@CaseyRobinson:いいえ、それは漸近的な振る舞いを特徴づけるものではない。たとえば、 O(n ^ 2)アルゴリズムは自動的に O(n ^ 3)になります。 | f(n)| となるような k があることを意味します。 <= k n ^ 2 。それは上の板です。
追加された 著者 Dennis,
@サルノール:私の悪い。私はあなたがクイックソートと挿入の並べ替えについて話していると思った。
追加された 著者 Dennis,
@CaseyRobinson:同じ記事の同じ段落から:大O表記の関数の説明は、通常、関数の成長率の上限を提供するだけです。
追加された 著者 Dennis,
Big Oh表記は上限ではありません。それは関数の漸近的挙動を特徴づける。
追加された 著者 Casey Robinson,
@Dennis from Wikipedia "Big O表記は、成長率に応じて機能を特徴付ける" en.wikipedia.org/wiki/ Big_O_notation
追加された 著者 Casey Robinson,
@デニス私たちは同じことを言っており、セマンティクスについて主張しています。
追加された 著者 Casey Robinson,

O() - 表記法は、一般的に、大きな問題のパフォーマンスを特性化するために使用されますが、意図的に一定のファクターと追加のオフセットを無視します。

これは重要なことです。一定の要因とオーバーヘッドはプロセッサ間や実装間で大きく異なる可能性があります.1602マシンでのシングルスレッドBasicプログラムのパフォーマンスは、Intel i7で実行されるCプログラムと同じアルゴリズムとは大きく異なりますクラスのプロセッサ。インプリメンテーションの最適化も要因であることに注意してください。他のすべての要因が同じであっても、細かい部分に注意を払うと、パフォーマンスが大幅に向上することがあります。

しかし、定数とオーバーヘッドは依然として重要です。アプリケーションでNが決して非常に大きくならないことが保証されている場合、O(N ^ 2)対O(N log N)の漸近的挙動は作用しません。

挿入の並べ替えはシンプルであり、小さなリストの場合、一般的には比較的類似したクイックソートまたはマージソートよりも高速です。そのため、実用的なソートの実装は、一般に、単一の要素まですべてをリカーする代わりに、「ベースケース」の挿入ソートのようなものに戻ってしまうのです。

4
追加された

Its a matter of the constants that are attached to the running time that we ignore in the big-oh notation(because we are concerned with order of growth). For insertion sort, the running time is O(n^2) i.e. T(n)<=c(n^2) whereas for Quicksort it is T(n)<=k(nlgn). As c is quite small, for small n, the running time of insertion sort is less then that of Quicksort.....

それが役に立てば幸い...

3
追加された

バイナリの挿入ソートはどうですか?バイナリ検索を使用して、スワップする位置を絶対に検索することができます。

0
追加された
スワップ位置は誤解です。挿入する位置で、スペースを取らなければなりません。ほとんどの場合、「配列」が暗示されています。すべての項目を「 位置」の片側に移動/コピーする必要があります。おそらく、リニア検索では触れられていないバイナリ検索の間に、 の位置の反対側にある項目のキーを読み取ったことがあります。クリティカルパスへのキーアクセスには有害です。
追加された 著者 greybeard,
"array-copy" が支配的で、バルクコピーの場合はより低い定数で、O(n)よりも[バイナリの挿入ポイント]のほうが効率的です。
追加された 著者 greybeard,
同意する。それはトレードオフです。あなたはこの状況で選択する必要があります。バイナリサーチを使用すると、ステップが減り、挿入する位置がすぐにわかりますが、 "array-copy"を実行するためのスペースが必要になります。最悪の場合はまだ線形時間ですが、平均的にはO(n)よりも効果的だと思います
追加された 著者 Phát Phát,