- ベストアンサー
バブルソート
int a[] = {8,45,15,90,62,73,22}をバブルソートを使用して、降順で並べ替える。 以下の説明では、配列の要素数(ここでは7)をNとしている。 (1) a[N-1] と a[N-2] を比較し、a[N-1] が a[N-2] より大きい場合は、a[N-1] と a[N-2] を入れ替える。 同様に a[ j] が a[ j-1] より大きければ、a[ j] と a[ j-1] を入れ替える。 この操作を、j=N-1からiまで繰り返す。ただし、iは(1)の処理回数を表す値である。(初回を0とする) (2) (1)を i=0 から N-2 まで繰り返す。 (3) 以下の<実行例>を参考に、配列aのようその各値を標準出力する。 <実行例> 90 73 62 45 22 15 8 という問題なのですが、どうやってもうまく並び替えられません。 a[N-1] の処理はいらないのではないのですか? どのようにプログラムを書いたらいいのか教えて下さい。 あつかましいですが、できたら解説付きでお願いします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
問題文がごちゃごちゃしすぎていますね。 まず、バブルソートは正式(?)には隣接交換法といいます。隣同士を順番に交換していきます。 一番泥臭く考えれば、右端から左端へ何回移動すれば整列が完了するでしょうか。 最も悪条件は左端に一番小さいデータがあって、これを右端へ移動させると考えると(N-1)回であることはすぐわかりますね。つまり、隣同士を比較しながらの右から左への移動(比較回数はN-1回)が(N-1)回で整列が完了する事になります。 ところが、これには無駄があります。右から左へ動いていくとき、必ず一番大きいデータが左端へ移動していきます。1回目は1番大きいデータ、2回目は2番目に大きいデータという風にです。従って、一番左に行ったデータは次からは比較の対象からはずしていいのです。(余談ですが大きい泡ほど早く水面に達するという現象になぞらえて、泡ソート=バブルソートというあだ名がついています。) 従ってfor文の2重ループが次の様になる事はお判りですね。 for( )…比較の対象範囲の左端を管理するループ(i=0~N-2) (最低でも2個ないと比較できないので、N-1でなく,N-2) for( )…1回ごとの比較の左端を管理するループ(j=(N-2)~i) (これはj-- である事に注意が必要です) >a[N-1] の処理はいらないのではないのですか? いります。問題の書き方がよくないだけです。 a[N-1] と a[N-2] の比較からはじめて 一般形としてa[ j] と a[ j-1] の比較をする。逆転があれば入れ替える。という風に読まないといけないのです。 わかりにくい問題文で苦労させられているご様子、同情します。
その他の回答 (2)
- imogasi
- ベストアンサー率27% (4737/17070)
下記はVBAでやって見ました。ご参考になれば。 何となく、質問の例の配列の要素(添え字)は理解し難い。 (B)のところは1回左より右へ比較が終わると、最小 が右のほうのJ+1番目に決まるので 第1回目 0から5まで 第2回目 0から4まで ・・・・ と1つずつ減っていく。 それで(A)のところで5から1づつ減る変数jを5から 0まで1づつ減らしている。 Sub test01() a = Array(8, 45, 75, 90, 62, 73, 22) For j = 5 To 0 Step -1 '-----(A) For i = 0 To j '-------------(B) If a(i) > a(i + 1) Then Else W = a(i) a(i) = a(i + 1) a(i + 1) = W End If Next i Next j '------ For i = 0 To 6 Debug.Print a(i) Next i End Sub
お礼
お礼が遅れましてすみません。 わざわざのご回答ありがとうございました。 かかれてあることをちょっとずつ噛み締めて、なんとか成功することが出来ました。
- taka_tetsu
- ベストアンサー率65% (1020/1553)
これぐらいの個数でしたら、並びの変化を目で見ながら追っていくと理解しやすいですよ。 初期値 8,45,15,90,62,73,22 1回目 90,8,45,15,73,62,22 2回目 90,73,8,45,15,62,22 3回目 90,73,62,8,45,15,22 4回目 90,73,62,45,8,22,15 5回目 90,73,62,45,22,8,15 6回目 90,73,62,45,22,15,8 というように、最高6回のループでソートが完了します。 つまり、N-1回です。 (2)のN-2と書くとわかりづらいかもしれませんね。 for文で書くと、 for(i = 0; i < N-1; i++ ) こんな感じになります。 あと、バブルソートは、1回ループが終了するごとに先頭の値が決定するので比較の回数が1回ずつ少なくなっていくのがポイントです。 例: 2回目のループのとき、1回目で先頭にきた90と73の比較を行う必要はない。 こんな感じですかね。 バブルソートくらいですと、ソースを書くと答えになってしまうので・・・ そのまま書くと勉強にならないですし。
お礼
お礼が大変送れて申し訳ありません。 一から動きを確認し、少しずつ動かしていったらなんとか出来ました。 本当に初心者でお恥ずかしい。 ありがとうございました。
お礼
すみません、お礼が遅れました。 細かく、そしてわかりやすく説明してくださってありがとうございました。 読めば読むほどややこしくて…。 なんとか成功しました。