アルゴリズムとプログラミング
(Algorithms and Programming)
第8回:多次元配列、ソーティング
•多次元配列行列クラスのサンプルプログラム
•ソーティングアルゴリズム選択ソートマージソートクイックソート
•多次元配列行列クラスのサンプルプログラム
•ソーティングアルゴリズム選択ソートマージソートクイックソート
講義資料等: http://www.pe.titech.ac.jp/~watanabe/lecture/ap/index-j.html
2次元配列• 行列は2次元配列で表すことができる
double a[ ][ ] = new double[3][3] ;
2次元配列 (3x3)の宣言 (要素が doubleの場合 ):
333231
232221
131211
aaa
aaa
aaa
]2][2[]1][2[]0][2[
]2][1[]1][1[]0][1[
]2][0[]1][0[]0][0[
aaa
aaa
aaa
a[ ][ ] (添え字: 0,1,2,3.....)例) 3x3行列
多次元配列
• 3次元配列: a[ ][ ][ ]
• 4次元配列: a[ ][ ][ ][ ]
( 各添え字を x,y,z 座標と対応させて 3 次元静電ポテンシャルなど
を表現 )
class Max2 { // 2x2 配列クラス ( 配列要素は double) private double m[][]; // フィールドとして配列参照変数を宣
言 // コンストラクタ ( 配列の実体を生成し、初期値を与える ) Max2(double a00,double a01,double a10, double a11 ){ m = new double[2][2] ; //new で配列の実体を生成する m[0][0] = a00; m[0][1] = a01; m[1][0] = a10; m[1][1] = a11; } void add( Max2 max ) { // 引数の配列を自身に加算 m[0][0] += max.m[0][0]; m[0][1] += max.m[0][1]; m[1][0] += max.m[1][0]; m[1][1] += max.m[1][1]; } void printMatrix() { System.out.print( "a00=" + m[0][0] ); System.out.println( " a01=" + m[0][1] ); System.out.print( "a10=" + m[1][0] ); System.out.println( " a11=" + m[1][1] ); }}
class Max2 { // 2x2 配列クラス ( 配列要素は double) private double m[][]; // フィールドとして配列参照変数を宣
言 // コンストラクタ ( 配列の実体を生成し、初期値を与える ) Max2(double a00,double a01,double a10, double a11 ){ m = new double[2][2] ; //new で配列の実体を生成する m[0][0] = a00; m[0][1] = a01; m[1][0] = a10; m[1][1] = a11; } void add( Max2 max ) { // 引数の配列を自身に加算 m[0][0] += max.m[0][0]; m[0][1] += max.m[0][1]; m[1][0] += max.m[1][0]; m[1][1] += max.m[1][1]; } void printMatrix() { System.out.print( "a00=" + m[0][0] ); System.out.println( " a01=" + m[0][1] ); System.out.print( "a10=" + m[1][0] ); System.out.println( " a11=" + m[1][1] ); }}
2x2行列を表現するクラス定義の例)
class SampleMax2 {
public static void main(String[] args) {
Max2 m1 = new Max2(1,0,3,0);
Max2 m2 = new Max2(0,2,0,4);
m1.add(m2); //add() の定義から m1=m1+m2 と等価 m1.printMatrix(); // 行列要素の表示 }
}
class SampleMax2 {
public static void main(String[] args) {
Max2 m1 = new Max2(1,0,3,0);
Max2 m2 = new Max2(0,2,0,4);
m1.add(m2); //add() の定義から m1=m1+m2 と等価 m1.printMatrix(); // 行列要素の表示 }
}
SampleMax2.java 続き
a00=1.0 a01=2.0a10=3.0 a11=4.0
実行結果
多次元配列の宣言(長さが不均一な場合)
double m[][] = new double[3][] ;m[0] = new double[2];m[1] = new double[4];m[2] = new double[3];
double m[][] = new double[3][] ;m[0] = new double[2];m[1] = new double[4];m[2] = new double[3];
m[0][0] m[0][1]
m[1][0] m[1][1] m[1][2] m[1][3]
m[2][0] m[2][1] m[2][2]
m[0]
m[1]
m[2]
空白のまま
数値計算では使わないが文字列を配列に格納する際に多用する
多次元配列の初期化
int n[][] = { { 3, 2 }, { 1, 8, 9, -1 }, { 0, 6, 4 }};
int n[][] = { { 3, 2 }, { 1, 8, 9, -1 }, { 0, 6, 4 }};
初期化要素を直接指定する場合
3 2
1 8 9 -1
0 6 4
n[0]
n[1]
n[2]
n[ ][0] n[ ][1] n[ ][2] n[ ][3]
配列長を知る (.length)
int n[][] = { { 3, 2 }, { 1, 8, 9, -1 }, { 0, 6, 4, 1, 7 }};
int n[][] = { { 3, 2 }, { 1, 8, 9, -1 }, { 0, 6, 4, 1, 7 }};
それぞれの次元の配列長は下記のようになる
n.length 3 になる. new int[3][] に対応n[0].length 2 になる. new int[2] に対応n[1].length 4 になる. new int[4] に対応n[2].length 5 になる. new int[5] に対応
n.length 3 になる. new int[3][] に対応n[0].length 2 になる. new int[2] に対応n[1].length 4 になる. new int[4] に対応n[2].length 5 になる. new int[5] に対応
例)
ソーティングアルゴリズム
•選択ソート•マージソート•クイックソート•バブルソート•ヒープソート
選択ソートの考え方問題:与えられた配列の要素を、大きい順に並べ替えなさい与えられた配列の要素を、大きい順に並べ替えなさい
方針 (例 ): 配列の先頭から、一つ一つ順番に値を比べて、大きい値と出会ったら入れ替える
a[0]a[1]a[2]
配列添え字 i
配列添え字 jwork 入れ替え用
一時記憶変数
a[3]a[4]
選択ソートのアルゴリズム
1. i = 0 からはじめる.2. A[i+1] から A[N-1] までの要素 A[j] と、 A[i] の大きさを比較して、3. もし、 A[i] よりも大きい要素に出会ったら、4. A[i] と A[j] を入れ替える.5. i = i + 1 とする.6. i == N - 1 ならば処理を終了する.そうでなければ, 2へ戻る.
計算量N×N = N2 のオーダーの計算量が必要となる.
class SampleAPP0701 { public static void main(String[] args) { int array[] = {20,100,-40,500,70};// 与えられた配列 int work; // 入れ替え用の一時メモリ for(int i = 0; i < array.length - 1; i++ ){ for(int j = ; j < ; j++ ){ if( array[i] < array[j] ) { // 大きな数字と出会った
ら work = array[ ]; // 入れ替える array[ ] = array[ ]; array[ ] = work; } } } // 以下は結果の表示 for(int i=0; i < array.length; i++ ){ System.out.println( "array[" + i + "]= " + array[i] ); } }}
class SampleAPP0701 { public static void main(String[] args) { int array[] = {20,100,-40,500,70};// 与えられた配列 int work; // 入れ替え用の一時メモリ for(int i = 0; i < array.length - 1; i++ ){ for(int j = ; j < ; j++ ){ if( array[i] < array[j] ) { // 大きな数字と出会った
ら work = array[ ]; // 入れ替える array[ ] = array[ ]; array[ ] = work; } } } // 以下は結果の表示 for(int i=0; i < array.length; i++ ){ System.out.println( "array[" + i + "]= " + array[i] ); } }}
SampleAPP0701.java
マージソートの考え方ソーティングされた複数のデータをまとめて、1つのソーティングしたデータにすることをマージ(merge,併合)と呼ぶ
2つのデータグループが既にソーティングされている場合、これらをまとめて順番に並べる変えるのは、ばらばらなデータを並べ直すのよりはるかに少ない手数で可能。
+ =
+
マージの手順
小さい順(昇順)の場合なら、常に一番小さい先頭データ同士のみを比較すれば十分である
+
マージの手順
小さい順(昇順)の場合なら、常に一番小さい先頭データ同士のみを比較すれば十分である
比較の上、小さい方を持ってくる
+
マージの手順
小さい順(昇順)の場合なら、常に一番小さい先頭データ同士のみを比較すれば十分である
+
マージの手順
小さい順(昇順)の場合なら、常に一番小さい先頭データ同士のみを比較すれば十分である
+
マージの手順
小さい順(昇順)の場合なら、常に一番小さい先頭データ同士のみを比較すれば十分である
+
マージの手順
小さい順(昇順)の場合なら、常に一番小さい先頭データ同士のみを比較すれば十分である
+
マージの手順
小さい順(昇順)の場合なら、常に一番小さい先頭データ同士のみを比較すれば十分である
+
マージの手順
小さい順(昇順)の場合なら、常に一番小さい先頭データ同士のみを比較すれば十分である
+
マージの手順
小さい順(昇順)の場合なら、常に一番小さい先頭データ同士のみを比較すれば十分である
+
マージの手順
小さい順(昇順)の場合なら、常に一番小さい先頭データ同士のみを比較すれば十分である
+
マージの手順
小さい順(昇順)の場合なら、常に一番小さい先頭データ同士のみを比較すれば十分である
+
マージの手順
小さい順(昇順)の場合なら、常に一番小さい先頭データ同士のみを比較すれば十分である
+
マージの手順
小さい順(昇順)の場合なら、常に一番小さい先頭データ同士のみを比較すれば十分である
マージソートの考え方(例)8つの要素を4つづつに分解
それぞれ
マージソートの考え方(例)先の手順を、分解されたグループに繰り返し適用する
マージの繰り返し
マージソートの計算量
log2N段
要素数 N
各段で N回のオーダーの比較と代入の操作が必要
∴N・ log2Nのオーダー
まとめ
•多次元配列宣言と初期化配列の長さ知る方法行列クラスのサンプルプログラム
•ソーティング (並べ替え )アルゴリズム
選択ソートマージソートクイックソート
•多次元配列宣言と初期化配列の長さ知る方法行列クラスのサンプルプログラム
•ソーティング (並べ替え )アルゴリズム
選択ソートマージソートクイックソート