リスト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 |
著作者 | 紀平拓男・春日伸弥 |
出版社 | ソフトバンク パブリッシング株式会社 |