リスト1が配列sortに格納された整数を昇順に並び替えるプロ グラムである.このプログラムの動作を考えるために,データ数をNとして, sort[0]を左端,sort[N]を右端とする.すると,以下のことが分かる.
このプログラムでは,doループ中の11行目の
if(sort[i]>sort[i+1])
最初のデータの並び方により,
回から
まで開きがある.初期位置と整列終
了位置との差の最大の期待値を計算することになるが,それは
程度であ
ることは分かるだろう.最小値の初期位置と整列終了位置との差の期待値である.この
程度とすると,先の比較の実行回数は,
![]() |
(1) |
この
に比例して計算量が必要な場合,
と書く.この表記法を
記法(
-notation)といい,計算オーダーを示す.数学で使うランダウの記
号に似ている.バブルソートの計算のオーダーは,
である.
1 void BubbleSort(void)
2 {
3 int i,j,flag;
4
5 do
6 {
7 flag=0;
8 for(i=0;i<N-1;i++)
9 /* 先頭から順に見ていって */
10 {
11 if(sort[i]>sort[i+1])
12 /* 左右の並びがおかしければ */
13 {
14 /* 入れ替える */
15 flag=1;
16 j=sort[i];
17 sort[i]=sort[i+1];
18 sort[i+1]=j;
19 }
20 }
21 /* 1度も並べ替えをせずに見終わったら終了 */
22 } while(flag==1);
23 }
1 void QuickSort(int bottom,int top,int *data)
2 {
3 int lower,upper,div,temp;
4 if(bottom>=top)
5 return;
6 /* 先頭の値を「適当な値」とする */
7 div=data[bottom];
8 for(lower=bottom,upper=top;lower<upper;)
9 {
10 while(lower<=upper&&data[lower]<=div)
11 lower++;
12 while(lower<=upper&&data[upper]>div)
13 upper--;
14 if(lower<upper)
15 {
16 temp=data[lower];
17 data[lower]=data[upper];
18 data[upper]=temp;
19 }
20 }
21 /* 最初に選択した値を中央に移動する */
22 temp=data[bottom];
23 data[bottom]=data[upper];
24 data[upper]=temp;
25
26 QuickSort(bottom,upper-1,data);
27 QuickSort(upper+1,top,data);
28 }
1 void MergeSort(int n,int x[])
2 {
3 int i,j,k,m;
4 if(n<=1)
5 return;
6 m=n/2;
7
8 /* ブロックを前半と後半に分ける */
9 MergeSort(m,x);
10 MergeSort(n-m,x+m);
11
12 /* 併合(マージ)操作 */
13 for(i=0;i<m;++i)
14 buffer[i]=x[i];
15 j=m;
16 i=k=0;
17 while(i<m&&j<n)
18 {
19 if(buffer[i]<=x[j])
20 x[k++]=buffer[i++];
21 else
22 x[k++]=x[j++];
23 }
24 while(i<m)
25 x[k++]=buffer[i++];
26 }
1 void CombSort(void)
2 {
3 int i,temp,flag,gap;
4 gap=N;
5
6 do
7 {
8 gap=(gap*10)/13;
9 /* 収縮率は1.3(gapが毎回1/1.3になる) */
10 if (gap==0)
11 gap=1;
12
13 flag=1;
14 /* 先頭から順に見ていって */
15 for (i=0; i<N-gap; ++i)
16 {
17 /* 距離がgapだけ離れた要素を比較し,
18 並びがおかしければ */
19 if (sort[i]>sort[i+gap])
20 {
21 /* 入れ替える */
22 flag=0;
23 temp=sort[i];
24 sort[i]=sort[i+gap];
25 sort[i+gap]=temp;
26 }
27 }
28
29 /* 1度も並べ替えをせずに,gap=1で見終わったら終了 */
30 } while((gap>1) || flag!=1);
31 }
1 void InsertSort(void)
2 {
3 int i,sorted,temp,insert;
4
5 /* 最初から最後まですべてソート済みになるまで繰り返す */
6 for(sorted=0; sorted<N-1; ++sorted)
7 {
8 /* ソート済み領域の直後の値を取り出す */
9 insert=sort[sorted+1];
10
11 /* 挿入する場所を見つける(リニアサーチ) */
12 for(i=0; i<=sorted; ++i)
13 if(sort[i]>insert)
14 break;
15
16 /* ソート済み領域直後の値を挿入する */
17 while(i<=sorted+1)
18 {
19 temp=sort[i];
20 sort[i]=insert;
21 insert=temp;
22 ++i;
23 }
24 }
25 }
1 void BinaryInsertSort(void)
2 {
3 int i,sorted,temp,insert;
4 int left,mid,right; /* バイナリサーチ用の追加変数 */
5
6 /* 最初から最後まですべてソート済みになるまで繰り返す */
7 for(sorted=1; sorted<N; ++sorted)
8 {
9 /* ソート済み領域の直後の値を取り出す */
10 insert=sort[sorted];
11
12 /* 挿入する場所を見つける(バイナリサーチ) */
13 left=0;
14 right=sorted;
15 while(left<right)
16 {
17 mid=(left+right)/2;
18
19 if(sort[mid]<insert)
20 left=mid+1;
21 else
22 right=mid;
23 }
24 i=left;
25
26 /* ソート済み領域直後の値を挿入する
27 (単純挿入ソートと同じ) */
28 while(i<=sorted)
29 {
30 temp=sort[i];
31 sort[i]=insert;
32 insert=temp;
33 ++i;
34 }
35 }
36 }
これら学習したソートの計算量と安定性については,表 1(教科書の Table 1-2)のとおりである.
[転載について]
このペー
ジ中のリスト1とリスト2,リスト3,リスト4,リスト5,リスト6のプロ
グラムは,教科書として使用している以下の書籍
| 書名 | プログラミングの宝箱 アルゴリズムとデータ構造 ISBN4-7973-2419-8 |
| 著作者 | 紀平拓男・春日伸弥 |
| 出版社 | ソフトバンク パブリッシング株式会社 |