もう一つの並べ替え

バブルソート

隣り合った2個のデータを比較し、順番が正しくない時には交換するという処理を繰り返す方法もあります。

プログラム名 OokiiJun11.java

public class OokiiJun11 {
    public static void main( String[] args ) {
        int[] data = { 52, 46, 24, 12, 15,
                       35, 18, 56, 63, 23,
                       10, 98, 29, 32, 90,
                       45, 64,  8, 16, 82
                     };
        int tmp ;
        for( int jn = 0; jn<data.length-1; jn++ ){
            for( int i=0; i<data.length-1; i++ ) {
                if( data[i] < data[i+1] ){
                     tmp       = data[i];   //この3行で値の交換
                     data[i]   = data[i+1];
                     data[i+1] = tmp;
                }
            }
        }
        for (int i = 0; i < data.length; i++) {
            System.out.print(data[i] + " ");
        }
        System.out.println();
    }
}

動作結果

$ java OokiiJun11
98 90 82 64 63 56 52 46 45 35 32 29 24 23 18 16 15 12 10 8

2つのforとif文だけでとても単純です。ifのブロックには3行ありますが、要するにdata[i]とその隣のdata[i+1]を交換しているだけです。

「順番が正しくない時には交換」という作業を2回のforでやっただけで正しい結果がでるということに納得するのは難しいかも知れませんが、プログラムはすっきりと書けます。

forは全データにわたりやっています。data.length-1 と -1 が入るのは、data[i+1] と、中で +1 されるからです。

改良

ただし、data.length-1の部分は冗長(無駄があるの意)です。下図をみてください。赤い部分は変化していません。すでに並び替えが決定した部分です。OokiiJun11.javaではここも毎回ちゃんと並んでいるかいらないチェックをしています。

52 46 24 12 15 35 18 56 63 23 10 98 29 32 90 45 64 8 16 82
52 46 24 15 35 18 56 63 23 12 98 29 32 90 45 64 10 16 82 8
52 46 24 35 18 56 63 23 15 98 29 32 90 45 64 12 16 82 10 8
52 46 35 24 56 63 23 18 98 29 32 90 45 64 15 16 82 12 10 8
52 46 35 56 63 24 23 98 29 32 90 45 64 18 16 82 15 12 10 8
52 46 56 63 35 24 98 29 32 90 45 64 23 18 82 16 15 12 10 8
52 56 63 46 35 98 29 32 90 45 64 24 23 82 18 16 15 12 10 8
56 63 52 46 98 35 32 90 45 64 29 24 82 23 18 16 15 12 10 8
63 56 52 98 46 35 90 45 64 32 29 82 24 23 18 16 15 12 10 8
63 56 98 52 46 90 45 64 35 32 82 29 24 23 18 16 15 12 10 8
63 98 56 52 90 46 64 45 35 82 32 29 24 23 18 16 15 12 10 8
98 63 56 90 52 64 46 45 82 35 32 29 24 23 18 16 15 12 10 8
98 63 90 56 64 52 46 82 45 35 32 29 24 23 18 16 15 12 10 8
98 90 63 64 56 52 82 46 45 35 32 29 24 23 18 16 15 12 10 8
98 90 64 63 56 82 52 46 45 35 32 29 24 23 18 16 15 12 10 8
98 90 64 63 82 56 52 46 45 35 32 29 24 23 18 16 15 12 10 8
98 90 64 82 63 56 52 46 45 35 32 29 24 23 18 16 15 12 10 8
98 90 82 64 63 56 52 46 45 35 32 29 24 23 18 16 15 12 10 8
98 90 82 64 63 56 52 46 45 35 32 29 24 23 18 16 15 12 10 8

jnを一回やると最小のもの(いまは8)がdataの最後に来ます。これはもう比べる必要がありませんから次の i は一つ少なくていい。jn をやるたびに i の最後は一つ少なくていいのです。

じっくり考えて、data.length-1-jn までやればよいということがわかります。

プログラム名 OokiiJun12.java

public class OokiiJun11 {
    public static void main( String[] args ) {
        int[] data = { 52, 46, 24, 12, 15,
                       35, 18, 56, 63, 23,
                       10, 98, 29, 32, 90,
                       45, 64,  8, 16, 82
                     };
        int tmp ;
        for( int jn = 0; jn<data.length-1; jn++ ){
            for( int i=0; i<data.length-1-jn; i++ ) {
                if( data[i] < data[i+1] ){
                     tmp       = data[i];   //この3行で値の交換
                     data[i]   = data[i+1];
                     data[i+1] = tmp;
                }
            }
        }
        for (int i = 0; i < data.length; i++) {
            System.out.print(data[i] + " ");
        }
        System.out.println();
    }
}

これが近接交換方式の並べ替えでバブルソートとよばれる種類の典型的な例です。

課題

1.

小さい順に並べるプログラムにしなさい。

最小値を左に集める方法と,最大値を右に集める方法がある。

プログラム名 ChiisaiJun11.java

もくじ

Javaプログラミング
聖愛中学高等学校
http://www.seiai.ed.jp/
Dec.2003
Dec.2008
Dec.2011