今回はマージソートを実装してみます。
マージソートは平均計算量、最良計算量、最悪計算量がすべて(n logn)と安定したソートアルゴリズムとして知られています。
考え方は、「配列の全ての要素を最小限まで分解し、その後要素の大小を比較して結合する」です。
実装したコードはこちらになります。
import java.util.*;
public class Algorithm{
public static void main(String[] args){
// 配列を生成する。
Random r = new Random();
int[] array = new int[10];
for (int i = 0; i < array.length; i++){
array[i] = r.nextInt(50);
}
print(array);
mergeSort(array); // ソートを行う。
print(array);
}
static void mergeSort(int[] array){
int len = array.length;
// もし配列の長さが1なら分解不可能なので抜け出す
if (len == 1){
return;
}
// 半分に分割し、2つの新しい配列を作成してさらに分割する。
int m = array.length / 2;
int n = array.length - m;
int[] mArray = new int[m];
int[] nArray = new int[n];
// 分割範囲内の値を配列に格納
for (int i = 0; i < m; i++){
mArray[i] = array[i];
}
for (int i = 0; i < n; i++){
nArray[i] = array[m + i];
}
// 再帰的に分解を行う
mergeSort(mArray);
mergeSort(nArray);
// 結合準備
int mLength = mArray.length;
int nLength = nArray.length;
int i = 0, j = 0;
// 分割したサイズよりもi, jどちらかが小さい場合
while (i < mLength || j < nLength){
/*
以下の条件式に当てはまるもの
・iがmLengthよりも小さく、かつnArray[j]よりもmArray[i]の値のほうが大きかった場合
・jがnLengthよりも大きい場合(つまりmArrayにしか要素がない場合)
*/
if (j >= nLength || (i < mLength && mArray[i] <= nArray[j])){
array[i + j] = mArray[i];
i++;
}else{ // それ以外
array[i + j] = nArray[j];
j++;
}
}
}
static void print(int[] array) {
for (int i = 0; i < array.length; i++) {
if (i != 0) {
System.out.print(" ");
}
System.out.print(array[i]);
}
System.out.println();
}
}
結合部分で少し苦戦しましたが、結合部分の条件分岐さえ理解すればどんなことをしているのかわかると思います。
次回はヒープソートを実装してみたいと思います!