データ構造基盤集計ソートjava実装
java実装の集計ソート
実現構想.シーケンスは、隣接する2つの要素ごとに集計され、n/2のシーケンスが得られ、各シーケンスは2つの要素を含む. は、上記のシーケンスをさらに集計する、各シーケンスには4つの要素 がある.手順2 を繰り返す最後のステップは、2つのシーケンスの合計長が元の配列の長さ である2つのシーケンスを集計することである.
クイックソートとの比較の集計ソートには追加の空間が必要であり、空間複雑度はO(n)であり、高速で追加の空間を必要としない は安定であり、速い列は安定ではない である.の2つのソートは実は少し分治法の味がして、ソートを小さな問題に分解して、これらの問題を組み合わせて原問題の解を得ました. 高速は、まず元の配列を2つのブロックに分割し、1つは中間位置の値より小さく、1つは中間位置の値より大きい.各ブロックの要素の数が1になるまで、各ブロックを繰り返します.大きいものから小さいものへ. は、単一要素ごとに集計され、2つの要素を含むシーケンスを集計し、上記の手順を繰り返します.小さい頃から大きいです.
まず統合アルゴリズムを実現します
コードは次のとおりです.
一度に合併する.
各秩序テーブルの長さがrangeであると仮定すると、数字はlength/rangeサブシーケンス:0~range-1;range ~ range*2-1;などなど.注意:秩序テーブルの個数は偶数で、長さはrangeです.-秩序テーブルの長さが奇数(最後のサブ継続テーブルが空であり、考慮されない)-秩序テーブルの長さは偶数であり、最後のサブシーケンスの長さはrangeより小さい
にじゅうマージソート
ここでは前回の集計の繰り返し呼び出しですが、range値を呼び出すたびに2倍になります.range最大はrange*2がdata以上である.lengthの時.
テストプログラム
しゅつりょく
上の出力から集計の過程がわかります.
参考記事
http://student.zjzk.cn/course_ware/data_structure/web/paixu/paixu8.5.1.1.htm
実現構想.
クイックソートとの比較
まず統合アルゴリズムを実現します
コードは次のとおりです.
* ,
*
* @param data
*
* @param low
*
* @param mid
* , mid+1
* @param high
*
*/
private static void merge(Integer[] data, int low, int mid, int high) {
if (mid < low || high < mid) {
return;
}
//
System.out.println("2Arrays:" + Arrays.toString(Arrays.copyOfRange(data, low, mid + 1))
+ Arrays.toString(Arrays.copyOfRange(data, mid + 1, high + 1)));
// , ,
Integer[] temp = new Integer[high - low + 1];
int l = low;
int m = mid + 1;
int i = 0;
while (l <= mid && m <= high) {
if (data[l] < data[m]) {
temp[i++] = data[l++];
} else {
temp[i++] = data[m++];
}
}
//
if (l <= mid) {
while (l <= mid)
temp[i++] = data[l++];
}
if (m <= high) {
while (m <= high)
temp[i++] = data[m++];
}
// k low , 0
int k = low;
for (int d : temp) {
data[k++] = d;
}
System.out.println("Merged: " + Arrays.toString(Arrays.copyOfRange(data, low, high + 1)));
}
一度に合併する.
各秩序テーブルの長さがrangeであると仮定すると、数字はlength/rangeサブシーケンス:0~range-1;range ~ range*2-1;などなど.注意:秩序テーブルの個数は偶数で、長さはrangeです.-秩序テーブルの長さが奇数(最後のサブ継続テーブルが空であり、考慮されない)-秩序テーブルの長さは偶数であり、最後のサブシーケンスの長さはrangeより小さい
/** * range * data.length/range * 3 : * 1. * 2. , * 3. , * * @param data * , 0 * @param length */
private static void mergePass(Integer[] data, int range) {
int i = 0;
// ,
while (i + 2 * range - 1 < data.length - 1) {
merge(data, i, i + range - 1, i + 2 * range - 1);
i = i + 2 * range; // i
}
// ,
if (i + range - 1 < data.length - 1) {
merge(data, i, i + range - 1, data.length - 1);
}
// ,
// ? ?
}
にじゅうマージソート
/** * * @param data */
private static void mergeSort(Integer[] data) {
//len
int len = 1;
while (len < data.length) {
mergePass(data, len);
len *= 2;
}
}
ここでは前回の集計の繰り返し呼び出しですが、range値を呼び出すたびに2倍になります.range最大はrange*2がdata以上である.lengthの時.
テストプログラム
public static void main(String[] args) {
Random r = new Random();
Integer[] data = new Integer[r.nextInt(10) + 8];
for (int ii = 0; ii < 10; ii++) {
for (int i = 0; i < data.length; i++) {
data[i] = r.nextInt(30);
}
System.out.println("------------------------");
System.out.println(Arrays.toString(data));
mergeSort(data);
System.out.println(Arrays.toString(data));
}
しゅつりょく
------------------------
[8, 2, 4, 11, 9, 22, 23, 17, 1, 2, 25, 28, 15, 16, 9, 17]
2Arrays:[8][2]
Merged: [2, 8]
2Arrays:[4][11]
Merged: [4, 11]
2Arrays:[9][22]
Merged: [9, 22]
2Arrays:[23][17]
Merged: [17, 23]
2Arrays:[1][2]
Merged: [1, 2]
2Arrays:[25][28]
Merged: [25, 28]
2Arrays:[15][16]
Merged: [15, 16]
2Arrays:[9][17]
Merged: [9, 17]
2Arrays:[2, 8][4, 11]
Merged: [2, 4, 8, 11]
2Arrays:[9, 22][17, 23]
Merged: [9, 17, 22, 23]
2Arrays:[1, 2][25, 28]
Merged: [1, 2, 25, 28]
2Arrays:[15, 16][9, 17]
Merged: [9, 15, 16, 17]
2Arrays:[2, 4, 8, 11][9, 17, 22, 23]
Merged: [2, 4, 8, 9, 11, 17, 22, 23]
2Arrays:[1, 2, 25, 28][9, 15, 16, 17]
Merged: [1, 2, 9, 15, 16, 17, 25, 28]
2Arrays:[2, 4, 8, 9, 11, 17, 22, 23][1, 2, 9, 15, 16, 17, 25, 28]
Merged: [1, 2, 2, 4, 8, 9, 9, 11, 15, 16, 17, 17, 22, 23, 25, 28]
[1, 2, 2, 4, 8, 9, 9, 11, 15, 16, 17, 17, 22, 23, 25, 28] ------------------------
上の出力から集計の過程がわかります.
参考記事
http://student.zjzk.cn/course_ware/data_structure/web/paixu/paixu8.5.1.1.htm