第12講 並び替えの方法その1
第6話 隣項交換繰り返し法のエンジン部分解説
並び替えプログラムのエンジン
public static int h(int x[],int n){
int i,j,a,v,w;
for(i=0;i<n;i++){
v=0;
for(j=0;j<n-1;j++){
if(x[j]<x[j+1]){
w=x[j];
x[j]=x[j+1];
x[j+1]=w;
v++;
}
}
if(v==0)break;
}
return(i);
}
解説
さて、隣項交換繰り返し法の核部分を解説しましょう。
8,6,10,4,9の並び替えの交換されいく過程を見ながら、コードを読んでください。
8,6,10,4,9
8,6,10,4,9
8,10,6,4,9
8,10,6,4,9
8,10,6,4,9
8,10,6,9,4
これで一巡しました。
再度同じことを繰り返します。
8,10,6,9,4
10,8,6,9,4
10,8,6,9,4
10,8,6,9,4
10,8,9,6,4
10,8,9,6,4
2巡目で降順に並び替えるのに成功しました。
次の場合どうでしょうか。
4,9,3,8,10
動きを追ってみましょう。
4,9,3,8,10
9,4,3,8,10
9,4,3,8,10
9,4,3,8,10
9,4,8,3,10
9,4,8,3,10
9,4,8,10,3
1巡目が終わりです。
9,4,8,10,3
9,4,8,10,3
9,8,4,10,3
9,8,4,10,3
9,8,10,4,3
9,8,10,4,3
2巡目が終了しましたが、まだ降順になっていません。
3巡目に入ります。
9,8,10,4,3
9,8,10,4,3
9,10,8,4,3
9,10,8,4,3
9,10,8,4,3
3巡目終了時にもまだ、降順になっていません。
9,10,8,4,3
10,9,8,4,3
10,9,8,4,3
10,9,8,4,3
10,9,8,4,3
4巡目で降順に並び替えるのに成功しました。
本当は
for(i=0;i<n;i++){
・
・
}
はwhile文で行った方がよいわけです。
というのはループが何巡目に終了するかがわかっていないからです。
終了回数がわからないときは、while文を使うのです。
ですが、皆さんはまだwhile文を学んでいないので、
先の仮説『nこのデータならn巡以内に並び替えに成功する』に基づいてfor文で組んでみました。
仮説が正しくない場合、このfor文プログラムではアウトになりますが、
幸いなことに今まで、何万回も実験してきましたが、
『nこのデータならn巡以内に並び替えに成功する』という仮説の反例は見つかっていませんので、
仮説は正しいと考えて良さそうです。
2重ループの役割を確認しましょう。
for(i=0;i<n;i++){
・
}
は何巡目であるかを示しています。
for(j=0;j<n-1;j++){
if(x[j]<x[j+1]){
w=x[j];
x[j]=x[j+1];
x[j+1]=w;
v++;
}
}
はi+1巡目においてすべての隣項を比較して、右の方が大きいときに交換しています。
j<n-1ですから、一番最後の比較は
if(x[n-2]<x[n-1])
です。配列は添え字0から始まりますので、n項目はn-1でしたね。
さて、vの役割は何でしょうか。
vは隣項の交換の回数を調べています。
すべての隣項について調べ、すべて左の方が大きいとき交換は1回も行われません。
ですからvが0であったときすでに並び替えが終わっていること意味します。
それで強制的に
if(v==0)break;
でiのループを終了させています。
さて、これで解説は終わりにします。
さて、課題を出して今話を閉じましょう。
今回
for(i=0;i<n;i++){
v=0;
for(j=0;j<n-1;j++){
if(x[j]<x[j+1]){
w=x[j];
x[j]=x[j+1];
x[j+1]=w;
v++;
}
}
if(v==0)break;
}
をループ(for文)文で処理しましたが、
関数の再帰的呼び出しでもできます。
考えてみましょう。
第5話へ 第7話へ
VB講義へ
VB講義基礎へ
vc++講義へ第1部へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC++による C言語 入門 C++ 入門
基礎から応用まで第1部
初心者のための VC++による C言語 入門 C++ 入門
基礎から応用まで第2部
初心者のための
VC++による C言語 入門 C++ 入門 基礎から応用まで第3部