整列7

クイックソートの特徴

クイックソートは、バブルソートや選択ソートに比べて速いソートですが、他のソートとの比較よりも注目しなければならないことがあります。それは、データ数が多くなったときでもそれほど遅くならないということです。

実際に時間を計って

実際に時間を計ってもわかりますが、バブルソートや選択ソートはデータ数が2倍になると4倍の時間がかかります。クイックソートでは2.1〜2.2倍ぐらいです。これはひとえに分割して比較することから来ています。

ちょっと理屈で考えて

100個のデータを並べ替えるのに4秒かかったとします。データが2倍の200個になったなら、時間は4倍の16秒です。200個を2つに分けてそれぞれ整列させたら100個の整列が2回ですから時間も2回分の8秒で済みます。200個を大きいものと小さいものに2分できれば、100個づつ整列してあとであわせることで200個整列したことになります。大きいものと小さいものに分けるのに多少かかったとしても10秒程度で整列できます。

1000個ならどうでしょうか。数が10倍ですから時間は100倍で400秒です。これを100個づつ10グループに分けて並べれば時間は10倍の40秒です。分ける時間を入れても50秒程度でできます。

プログラムをみて手数を数えると

大きいものと小さいものに分ける時間は短いだろうと予測しましたが、そうでないかもしれません。そんなときにはプログラムをみて手数を数えるということが必要になります。バブルソートや選択ソートが O( n2 ) であるというのは、プログラムから比較の回数や代入の回数をおおざっぱに数えて出した結果です。n 個のデータを並べ替える手間はnの2乗ていどだというわけです。

クイックソートの手数は O( n log n ) 程度と調べられています。ここでは log n は正確には log2n で、 2=nであるような、kの値をいいます。

比べてみましょう。nlognがクイックソート、n2が選択・バブルソートです。nが4あたりまでは半分ですが、1000になると約9966は約10000と見なせるので、百分の1の手数で計算できることになります。これはnが大きくなるほど差が広がります。

log n nlogn2
16
10約3.3 約33100
100約6.64 約66410000
1000約9.966 約99661000000
2000約10.97 約21932 4000000
10000約13.29 約132877 100000000

グラフにしてみました

nが大きくなるともっと差が広がります。

注意1

「クイックソートは世の中で最も速いソートアルゴリズムとして知られています」と書きましたが、「クイックソートが最速」と暗記しないでください。もっと速いアルゴリズムが発見される(ている)かもしれません。手数が O( n log n ) 程度になるアルゴリズムは他にもあります。どのアルゴリズムが速いかというのはプログラム言語の種類にもよりますし、種類は同じでもシステムによって違うものなのです。

ですから、普通ソートアルゴリズムの優劣を考えるときは実際の速さでなく、手数の概算で考えます。これがデータの初期値の並び方によっても変わる場合があり、なかなか難しいのです。ある条件では O( n 1.2 ) 程度になるアルゴリズムも知られています。これは、 O( n log n ) よりも優秀です。

注意2

バブルソートや選択ソートはデータがnの時、手数が O( n2 ) で、データ数が2倍になったら、22=4倍になるというのはその通りです。でもnに2を代入してそうなるのではありません。(2n)2が、n2 の4倍であるということです。

従って、クイックソートの手数は O( n log n ) 程度ですが、データ数が2倍になったら、 n log n =2 1og22=2倍とはなりません。(2nの時の手数)÷(nの時の手数)で計算します。つまり(2n 1og22n)÷(n 1og2n)を計算することになります。


聖愛高等学校
http://www.seiai.ed.jp/