卒業研究報告書

 

ソートの原理

 

バブルソートの原理

先頭から後ろにスキャンして行き、隣合う要素の大小が逆だったら交換することを繰り返すアルゴリズムである。

 

選択ソートの原理

未整列部分から最小(大)値を選択し、先頭に持ってくることを

繰り返すアルゴリズムである。

 

挿入ソートの原理

整列済み配列の中の適切な位置に未整列要素を挿入することを繰り返すアルゴリズムである。

 

クイックソートのアルゴリズム

ある要素を枢軸とし、枢軸より小さい要素と大きい要素に振り分けることを

繰り返すアルゴリズムである。

 

マージソートのアルゴリズム

要素を半分に分割することを、要素が1つになるまで繰り返し、

整列しながら、各要素を結合することを繰り返すルゴリズムである。

 

 

実験手順

まず、各アルゴリズムのプログラムを作成・実行し、動作の原理を理解する。

昇順、降順、重複する数値を含むランダムな数列、重複する数値を含まないランダムな数列、

の4種類を使って実際に整列されているかを確かめる。

 

次に、整列プログラムを実行する時間を計測する(数列ファイルを読み込むなどの

時間は含まない)。数列ファイルの大きさは、5001000500010000を使った。

(ファイルの大きさは、210倍の要素が考えやすいので、この大きさにした)

 

その次に、整列プログラムで実行される比較回数と交換(代入)回数を計測する。

数列ファイルの大きさは時間計測と同じ、5001000500010000を使った。

 

 

 

 

各アルゴリズムの実験結果と考察

計測された時間は、少数点以下は「…000」「…333」「…667」のどれかで、(プログラムを工夫しないと)細かい時間は計測しきれないので少数点以下4桁目を四捨五入している。

(また、通常オーダーを表す時はnを使用するが、mを使用すると、u(平方メートルの単位)が使えて、二乗を表すのに便利なため、mを使ってオーダーを表現している)

 

1、バブルソート

バブルソートのプログラムの一部(交換・比較回数のカウントを表す)

for (i=0; i<m-1; i++)

for (j=m-1; j>i; j--) {

compare++; /* 比較のカウント */

if (a[j-1]>a[j]) {

exchange++; /* 交換のカウント */

t=a[j]; a[j]=a[j-1]; a[j-1]=t;

比較回数は、外側のfor文と内側のfor文の回数を掛けた値になる。

外側のfor文はm−1回行われ、内側のfor文は(最初はm−1回、最後が1回なので)平均m/2になる。

よって比較回数の理論値は

m-1 × m/2 u/2−m/2

になる。

また、比較回数の最大次数の項がu なのでバブルソートのオーダーはu になる。

 

図1−1 バブルソートの比較回数/交換回数

データの

並び方

要素数m

昇順

比較回数(回)

交換回数(回)

降順

ランダム

ランダム

(重複なし)

500

124750

124750

124750

124750

63197

124750

58334

1000

499500

499500

499500

499500

240764

499500

222242

5000

12497500

12497500

12497500

12497500

6233764

12497500

5619870

10000

49995000

49995000

49995000

49995000

24820080

49995000

22762526

 

m−1)×m/2

となった。(理論値と一致)

・整列する必要のない昇順でも同じ回数だけ比較することになる。

・ランダムのファイルの交換回数は、比較回数の半分に近い値になっている。

 

図1−2 バブルソートの実行時間と実行時間の理論値

データの

並び方

要素数m

昇順

実行時間(秒)

理論値(秒)

降順

ランダム

ランダム

(重複なし)

500

0.017

0.017

0.033

0.043

0.033

0.036

0.033

0.034

1000

0.067

0.066

0.183

0.171

0.150

0.142

0.133

0.136

5000

1.617

1.655

4.550

4.276

3.517

3.553

3.400

3.394

10000

6.517

6.621

18.717

17.104

14.583

14.213

14.200

13.575

・実行時間の理論値はデータファイル毎に実行時間÷各要素数のu の値を加算し、4で割り、その値を各要素数のu を掛けた値とした。

(例えば、昇順では、0.017÷250000 0.067÷1000000 1.617÷25000000 6.517÷100000000 の値を4で割った値を基準として、要素数が500なら、250000を掛けた値が実行時間の理論値となる。)

実験に使用したワークステーションの処理速度が速いことと、プログラムで計測できる時間の最小が0.0166 であったため、要素数500の実行時間は不正確である。(バブルソート以外のアルゴリズムでも不正確になってしまっている。)要素数500以外の3つは、実行時間÷u の値が近い値になっても、要素数500だけ、他とずれてしまうことがあり、その実行時間の理論値は、ずれてしまう。(バブルソートの場合、降順理論値は、要素数500だけ、理論値が大きくなってしまい、他3つは理論値の方が小さくなってしまう。)

降順以外は大体実行時間とその理論値は近い値になっている。

 

2、選択ソート

選択ソートのプログラムの一部(交換・比較回数のカウントを表す)

for(i=0 ; i<m-1 ; i++){

lowest = i;

lowkey = a[i];

for(j=i+1 ; j<m ; j++)

compare++; /* 比較回数のカウント */

if(a[j]<lowkey){

lowest = j; lowkey = a[j];

}

exchange++; /* 交換回数のカウント */

t=a[i];

a[i]=a[lowest];

a[lowest]=t;

}

・交換回数は外側のfor文のループ回数なので、(m−1)になる。

・比較回数はif文の実行回数なので内側のfor文のループ回数 m/2

と外側のfor文のループ回数m-1を掛けた値

m−1)×m/2 u/2− m/2

になる。

 

図2−1 選択ソートの比較回数/交換以外の代入回数(if文内でlowkeyに代入された回数)

データの

並び方

要素数m

昇順

比較回数(回)

交換以外の

代入回数(回)

降順

ランダム

ランダム

(重複なし)

500

124750

124750

62500

124750

2411

124750

1526

1000

499500

499500

250000

499500

5633

499500

3212

5000

12497500

12497500

6250000

12497500

35254

12497500

18380

10000

49995000

49995000

25000000

49995000

80166

49995000

35743

・選択ソートでは適切な要素を選んでから交換するので、どの種類のデータファイルでも

比較・交換回数は理論値と一致した。(要素数が10倍になれば,比較交換回数は100倍になる)

(図2では交換回数ではなく、if文の中で最小値の添え字(lowest)と最小値(lowkey)に代入が行われた回数を載せる。)

・降順では、要素数が2倍になれば、if文内でlowkeyに代入された回数は4倍になることが解る。

・降順でのif文内での代入回数は比較回数の半分に近い。これは、未整列部分の先頭(降順なら

最大値)と未整列部分の最小値が交換されるからである。

・降順以外の実行時間は比較・交換回数が同じなためあまり違いが出なかった。降順はif文の中のlowkeylowestへの代入がたくさん発生するので他よりも時間が掛かる。(lowkeyには一番左側の値を最初代入するので降順では未整列部分の最小値を代入することになり、比較する度にlowkeyへの代入が発生する。)

 

図2−2 選択ソートの実行時間/実行時間の理論値

データの

並び方

要素数m

昇順

比較回数(回)

交換以外の代入回数(回)

降順

ランダム

ランダム

(重複なし)

500

0.017

0.023

0.033

0.031

0.033

0.027

0.033

0.026

1000

0.100

0.090

0.117

0.124

0.100

0.107

0.100

0.107

5000

2.350

2.256

3.017

3.100

2.367

2.666

2.367

2.665

10000

9.967

9.025

12.633

12.633

9.983

10.663

9.967

10.688

実験に使用したワークステーションの処理速度が速いことと、プログラムで計測できる時間の最小が0.0166 であったため、要素数500の実行時間は不正確である。要素数500以外の3つは、実行時間÷u の値が近い値になっても、要素数500だけ、他とずれてしまうことがあり、その実行時間の理論値は、ずれてしまう。降順以外は実行時間とその理論値は少し離れてしまった。

・選択ソートを改善するには、最小値のlowkeylowestだけでなく、最大値もスキャン時に探すことによって、配列の両側から整列済みになり、実行時間が早くなると考えられる。

・スキャンする前のlowkeyへの代入を、左端・中央・右端の中の最小値を選べば、降順だけ少し実行時間が掛かるのを防ぐことができると考えられる。

 

 

3、挿入ソート

挿入ソートのプログラムの例(交換・比較回数のカウントを表す)

for (i=1; i<m; i++){

j=i;

 

while(1){

compare++; /* 比較回数 :/

if( !(j>=1 && a[j-1] > a[j]) )

break;

 

t=a[j]; a[j]=a[j-1]; a[j-1]=t;

j--;

exchange++; /* 交換回数 */

}

}

・挿入ソートはfor文がm−1回実行され,while文は平均i/2回実行されるため,挿入ソートのオーダーはu となり、参考文献と一致する。

 

図3−1 挿入ソートの比較回数/交換回数

データの

並び方

要素数m

昇順

比較回数(回)

交換回数(回)

降順

ランダム

ランダム

(重複なし)

500

499

125249

124750

63696

63197

58833

58334

1000

999

500499

499500

241763

240764

223241

222242

5000

4999

12502499

12497500

6238763

6233764

5624869

5619870

10000

9999

50004999

49995000

24830007

24820080

22712519

22762526

 

・昇順では、交換回数が0で、比較回数もm−1のため、時間が掛からず、要素数1万でも

実行時間が計測できなかった。

・実行時間順の大きい順に並べると、降順・ランダム・ランダム(重複なし)昇順となる。挿入ソートは昇順(もしくは昇順に近いと)高速である。逆に降順はバブルソートよりも遅くなってしまう。整列するファイルの並び方によって、実行時間が大きく変化するアルゴリズムである。

・ランダムの比較交換回数は降順の比較交換回数の半分に近い値になっている。乱数なので、バラつきがちょうど、降順(1番手間が掛かる)と昇順(1番手間が掛からない)の間の数であるとも言える。

 

図3−2 挿入ソートの実行時間と実行時間の理論値

データの

並び方

要素数m

昇順

実行時間(秒)

理論値(秒)

降順

ランダム

ランダム

(重複なし)

500

0.000

0.000

0.050

0.048

0.017

0.021

0.033

0.024

1000

0.000

0.000

0.183

0.191

0.083

0.085

0.083

0.096

5000

0.000

0.000

4.700

4.775

2.317

2.113

2.100

2.408

10000

0.000

0.000

19.333

19.100

9.450

8.455

8.633

9.633

・実行時間の理論値はデータファイル毎に実行時間÷各要素数のu の値を加算し、4で割り、その値を各要素数のu を掛けた値とした。

実験に使用したワークステーションの処理速度が速いことと、プログラムで計測できる時間の最小が0.0166 であったため、要素数500の実行時間は不正確である。要素数500以外の3つは、実行時間÷u の値が近い値になっても、要素数500だけ、他とずれてしまうことがあり、その実行時間の理論値はずれてしまう。

昇順はどの要素数でも0秒なので理論値と完全に一致した。

降順以外は実行時間とその理論値は少し離れてしまった。

 

・挿入ソートは隣り合った要素を比較しているので、離れた要素を比較するようにする(シェルソートの考えを使う)と実行時間が早くなると考えられる。

 

 

 

5、クイックソート

クイックソートのプログラムの一部(交換・比較回数のカウントを表す。compare++;が比較回数のカウントで,exchange++;が交換回数のカウント)

int partition(int a[],int l,int r)

{ int i,j,pivot,t;

i=l-1; j=r; /* ポインタijを初期化する */

pivot=a[r]; /* 一番右端の要素を枢軸にする */

for(;;){ /* ポインタijがぶつかるまで繰り返す */

while(a[++i] < pivot){ compare++; /* ポインタiを右へ進める */

} compare++;

while(i < --j && pivot <a[j]){ compare++; /* ポインタjを左へ進める */

} compare++;

if(i >= j) break; /* ポインタijがぶつかったらループを抜ける */

t=a[i]; a[i]=a[r]; a[r]=t; exchange++; /* iの指す要素とjの指す要素を交換する */

}

t=a[i]; a[i]=a[r]; a[r]=t; exchange++; /* a[i]と枢軸を交換する */

return i;

}

上のプログラムのように、whileでは真でも偽でも比較としてカウントし、交換回数はポインタ同士を交換しても、iと枢軸を交換してもカウントした。

図4−1 クイックソート比較回数/交換回数

データの

並び方

要素数m

昇順

比較回数(回)

交換回数(回)

降順

ランダム

ランダム

(重複なし)

500

125748

499

125498

499

6290

1197

5799

1144

1000

501498

999

500998

999

12660

2699

13140

2545

5000

12507498

4999

12504998

4999

77893

15607

83117

15360

10000

50014998

9999

50009998

9999

173285

33606

173016

33265

 

・昇順と降順の比較・交換回数が近くて、バブルソートの昇順と同じ位の実行速度になっている。

・ランダムのファイルでは要素数が500から5000になれば、交換・比較回数は13倍近くになり、m logmに比例していることが解る(5000 log5000 ÷ 500 log50013.3…)。

・昇順の1 の数列をクイックソートする場合、最大値が枢軸になると、枢軸より大きな値が無く、最大値である4だけの整列が終了し、1 の数列をソートしなければならず、1回のソートで整列が完了するのは1つだけなので手間が掛かる。

(改善するには、配列の左端・右端・中央の3つの中央値を枢軸に決めるようなプログラムにすると良くなると考えられる。)

 

図4−2 クイックソートの実行時間と実行時間の理論値(ランダムの2つは理論値が出せなかった)

データの

並び方

要素数m

昇順

実行時間(秒)

理論値(秒)

降順

ランダム

ランダム

(重複なし)

500

0.017

0.016

0.017

0.017

0.000

 

0.000

 

1000

0.067

0.065

0.067

0.067

0.000

 

0.017

 

5000

1.500

1.619

1.600

1.663

0.017

 

0.017

 

10000

6.417

6.475

6.750

6.650

0.033

 

0.033

 

u に比例していて、最悪の状態になっていることがわかる。

 

(u 3m −4)/2

である。

求めた手順

a[6]={1 6} の数列をクイックソートすると考える

関数partition内で1回目のスキャンでは、左から右に進めるポインタiは6回(A[0]A[1]A[2]A[3]a[4]a[5])、右から左に進めるポインタjは1回(A[5])、枢軸と比較する。そして、iが指すA[5]と枢軸A[5](自分同士)を交換し、要素が1つになったA[5]は整列終了。この手順を繰り返す。

E (Eは枢軸)ポインタiの比較回数は6回、ポインタjの比較回数は1

D iは5回、jは1

C iは4回、jは1

B iは3回、jは1

A iは2回、jは1

 

このように、昇順の数列では、要素が6つであれば、7回比較し、要素が6つであれば7回比較することから、要素+1回比較することが解る。また、要素数が1つになったらもうスキャンはしないので要素数2つのスキャンの比較回数3が最低値になる。

数列Aでは、比較回数が7+6+5+4+3のように等差数列の和になっている。

よって、昇順で要素数mのクイックソートの比較回数は初項m+1、末項が3で項数がm−1の等差数列の和となり、

m+1+3)/2×(m−1)

になるので (u 3m −4)/2 が求まる。

昇順の比較回数は、全て理論値と一致した。

 

m/2+m−2

である。

求めた手順

[6]={6 1}の数列をクイックソートすると考える。

@ iは1回、jは5回(1と6が交換され、1は整列終了)

E iは5回、jは1回

A iは1回、jは3回

B iは2回、jは1回

B iは2回、jは1回

 

比較回数は6、6、4、3、3となる。この数列は昇順の比較回数と近いので良く見ると

1回目、3回目、4回目では昇順の比較回数−1になっている。スキャンのうち約半分は、昇順−1回比較している。よって昇順の理論値から、項数/2を引くと

m+1+3)/2×(m−1)−m/2

m/2+m−2

が求まる。

降順の比較回数は、全て理論値と一致した。

 

昇順と降順の比較/交換回数を比べてみると、どの要素数でも交換回数は同じで、比較回数は昇順の方が多かった。昇順は並び換えしなくてもいいのに比較回数が降順より多くなるのはおかしいように思える。これは、昇順の場合必ず、ポインタiが右端の枢軸まで比較するが、降順の場合は2回に1回最大値が左端にあり、その時は、ポインタiもポインタjも枢軸を比較しない(ポインタjはプログラム上枢軸と比較することはない)ので、同じ要素数でも降順の方が、比較回数が少ないか同じになって比較回数は昇順の方が多くなる。

しかし、交換回数は同じで比較回数は昇順の方が少ないのに実行時間では、昇順方が早くなっている。これは関数partitionの中のポインタiとポインタjの比較回数の違いである。

ポインタiを比較しているwhile(a[++i] < pivot)とポインタjを比較しているwhile(i < --j && pivot <a[j])では、jを比較している文の方が、ループの条件が複雑である。ループの条件が複雑な方が少し時間が掛かる。iの比較回数とjの比較回数に差がたくさんあれば、実行時間に差が出て来るはずである。上に示した、昇順と降順の比較回数の理論値を説明する例において、iとjは図4−3のように比較回数が増える。

 

図4−3 要素数6の昇順と降順におけるポインタiとポインタjの比較回数

種類

ソート回数

昇順

iの比較回数

昇順

jの比較回数

降順

iの比較回数

降順

jの比較回数

1回目

2回目

3回目

4回目

5回目

合計

20

11

11

 

図4−3で解ることは、降順では、jが1回多いだけで、iとjの比較回数はあまり変わらないが、昇順では、条件が複雑でないiの方がかなり多くなる。

理論値を計算すると、昇順のiは(m+2)/2×(m−1)=(u+m−2)/2になり、

昇順のjはm−1になる。降順はiもjも比較回数の半分になる。

ところで、要素数10000で理論値を考えると昇順のiの比較回数は50004999回、昇順のjは9999回、降順のiとjは25004999回となる。これは、計測した値(iとjを別々にカウントするプログラム)と一致し理論値が正しいことが解った。

仮に条件が複雑になると、2倍実行速度が遅くなるとすると、要素数6の例では、昇順は20+5×2=30、降順は11+11×2=33で降順の方が3多くなる。また、倍率では、1.1倍の違いがある。比較回数だけでは降順の方が3回多いのに、条件文の実行速度の違いを考えると、昇順の方が、実行速度が早くなったのが説明できる。

(交換回数は同じで比較以外の手順に違いは無いから比較の違いが出ることになる。)

要素数10000では、昇順は500049999999×2=50024997、降順2500499925004999×2=750149971.5倍近い違いが出ることになるので、要素数が多ければ多い程違いが出やすい。

適当に選んで2倍で計算してみたが、参考文献によると、「ループ条件が複雑になっても、実行時間にさほど違いは出ない」とあるので、実験値で実行時間を計算してみる(交換回数は比較回数に比べて小さいので無視した)。要素数10000では、昇順/降順は1.05倍近く降順が遅くなっている。昇順のi+j×倍率/降順のi+j×倍率=1.05で倍率を計算すると、1.12になった。

この条件文の複雑さの倍率を、要素数6で考えると、昇順は25.6降順は23.32になる。

要素数10000で考えると、昇順は、50016198降順は、53010598になる。要素数が小さいと、

昇順の方が、時間が掛かり(大きな差ではない)、要素数が大きくなると降順の方がかなり時間が掛かることになる。

これらのことから、ループ条件の複雑さによって昇順の実行時間が降順よりも早くなった、ということが説明できると思われる。

 

 

・ランダムとランダム(重複なし)は実行時間が小さくて理論値が出せないので、m logmに比例しているかどうかわからなかった。要素数を増やすか、プログラムを工夫すべきだった。

昇順と降順の実行時間の理論値はデータファイル毎に実行時間÷各要素数のu の値を加算し、4で割り、その値を各要素数のu を掛けた値とした。

実験に使用したワークステーションの処理速度が速いことと、プログラムで計測できる時間の最小が0.0166 であったため、要素数500の実行時間は不正確である。要素数500以外の3つは、実行時間÷u の値が近い値になっても、要素数500だけ、他とずれてしまうことがあり、その実行時間の理論値は、ずれてしまう。

実験では、比較回数はm logmよりもかなり多い数になっている。これは、枢軸がちょうど中央値になっていないため、分割の作業の効率が悪いためである。

また、配列の右端を枢軸にしてしまうと、昇順や降順のような数列では非常に手間が掛かるので、配列の中央の値と右端の値と左端の値のうち中央値を選んで枢軸とすることで、最悪の事態を避けて、実行速度を早めることができると考えられる。

・クイックソートの作業用メモリは参考文献によると「平均でオーダー log m 」必要とあるので他の単純なソートアルゴリズム(使用メモリはオーダー 1)よりも使用するメモリが多い

・アルゴリズムが他のソートより複雑で理解するのに時間が掛かった。

 

 

 

6、マージソート

マージソートのプログラムの一部(交換・比較回数のカウントを表す。compare++;が比較回数のカウントで,exchange++;が交換回数のカウント)

/* 作業用配列bの両端から取り出したデータをマージして配列aに入れる */

i=low; j=high;

for(k=low;k<=high;k++){

compare++; exchange++;

if(b[i] <= b[j])

a[k] = b[i++];

else

a[k] = b[j--];

}

 

・比較回数はif文の実行回数なので要素数m掛ける、マージの実行回数(関数を呼び出す回数)logmになる。よってマージソートのオーダーはm logmになる。

・代入は、マージの時の比較を実行する度に行い、また、マージと同じ回数分だけ、分割時に代入を行っているため、比較回数の2倍の回数が代入回数である。

 

図5 マージソートの実行時間/比較回数(比較回数の理論値)

データの

並び方

要素数m

昇順・降順・ランダム・ランダム(重複なし)の4種類全て

実行時間(秒)

比較回数 実験値/理論値 m logm(回)

500

0.000

4488 4482

1000

0.000

9976 9966

5000

0.033

61818 61439

10000

0.067

133616 132877

 

・図5の理論値はm logmの小数点以下を四捨五入した。比較回数に少数点以下の数値はありえないので(要素数が3なら log3=4.75 だが、比較回数は5になり、理論値より少し大きくなる)実験値では、理論値よりも多い値になっている。

・どのようなデータであろうと、同じ手順でマージソートは分割後、比較をして結合するため、

比較・代入回数、実行速度共に要素数が同じならデータの種類によらず、同じ値になった。

(要素数を増やすか、プログラムを改善すべきだった)

(作業用配列を使わないプログラムにする場合は、かなりの手間がかかり現実的ではないらしい)

・クイックソートのランダムと比べてみると、比較回数はマージソートの方が少ないが、代入回数(クイックソートの交換回数×3とマージソートの比較回数×2を比べる)ではマージソートの方がかなり多くなり、実行時間もマージソートの方が多い。

また、作業用配列を大き目に宣言しておくのではなく、整列する配列と同じ大きさの領域を確保する(malloc関数を使う)ことによって無駄なメモリ消費を抑えることができると思われる。

 

 

 

まとめ

まず、3つの基本的なソートアルゴリズムを比較してみる。

 

要素数1万における基本ソートアルグリズムの比較回数/交換回数/実行時間

データの種類

 

ソートの種類

昇順 実行時間(秒)

比較回数(回)

交換回数(回)

降順

ランダム

ランダム

(重複なし)

バブルソート

6.517

49995000

18.717

49995000

49995000

14.583

49995000

24820080

14.200

49995000

22762526

選択ソート

9.967

49995000

12.633

49995000

25000000

9.983

49995000

80166

9.967

49995000

35743

挿入ソート

0.000

9999

19.333

50004999

49995000

9.450

24830007

24820080

8.633

22712519

22762526

・選択ソートは他と比べてもデータの種類によらず、実行速度にあまり変化が無いことがわかる。

 

 

5つのソートアルゴリズムの実行速度を比べてみる。

 

ランダムデータの各アルゴリズムにおける整列時間(秒)

アルゴリズム

要素数m

バブル

ソート

選択ソート

挿入ソート

クイックソート

マージソート

500

0.033

0.033

0.017

0.000

0.000

1000

0.150

0.100

0.083

0.000

0.000

5000

3.517

2.367

2.317

0.017

0.033

10000

14.583

9.983

9.450

0.033

0.067

 

・ランダムのデータを扱っているので、やはり名前の通り、クイックソートが一番速い。

また、マージソートもなかなか速く基本的な3つのソートとは雲泥の差が出た。グラフにするとその差がはっきりと解る。

・クイックソートもマージソートも、扱った要素数が小さく、時間測定は上手くいかなかった。

(改善するには、要素数をもっと増やすか、プログラム上で10回ソートを行い、実行に掛かった時間を10で割る、のようなことで他のアルゴリズムと比べやすいデータが取れたと考えられる)

 

 

 

結論

今までの研究から図8のようなことがわかった。

 

図8 各アルゴリズムの長所・短所

 

長所

短所

バブルソート

プログラミングしやすい

(覚えやすい作りやすい)

使用メモリが少ない

実行速度が全体的に遅い。

比較・交換回数が多い。

逆順の並びでは遅くなる

選択ソート

交換回数が非常に少ない。

データの並び方で交換・比較回数に変化があまり無く、実行時間が安定

使用メモリが少ない

比較回数が多い

逆順の並びになっていると少し遅くなる

挿入ソート

整列に近いデータの整列は高速

使用メモリが少ない

逆順のデータの整列に非常に弱い

交換回数が多い

クイックソート

もっとも高速

比較・交換回数が少ない

最悪のケースでは遅くなるので、回避するプログラムを作る必要がある

使用メモリが多目

マージソート

データの並び方に関係なく高速

比較・代入回数が少ない

(外部記憶の整列に応用できる)

メモリがたくさん必要

 

 

参考文献

近藤 嘉雪 『Cプログラマのためのアルゴリズムとデータ構造』