2.2.1 歸併排序的抽象方法
//2.2 歸併排序
// 要將一個數組排序,可以先(遞歸地)將它分成兩半分別排序,然後將結果歸併起來
// 優點:它能夠保證將任意長度爲N的數組排序所需時間和NlogN成正比
// 缺點:它所需的額外空間和N成正比。
private static void merge(Comparable[] a, int lo, int mid, int hi){
int i = lo;
int j = mid + 1;
for (int k=lo; k<=hi; k++){
aux[k] = a[k]; // 將a[lo..hi]複製到aux[lo..hi]
}
for (int k=lo; k<=hi; k++){
if (i > mid){
a[k] = aux[j++];
}else if (j > hi){
a[k] = aux[i++];
}else if (less(aux[j], aux[i])){
a[k] = aux[j++];
}else{
a[k] = aux[i++];
}
}
}
public class MergeSort {
private static Comparable[] aux; // 歸併所需的輔助數組
public static void sort(Comparable[] a){
aux = new Comparable[a.length]; // 一次性分配空間
sort(a, 0, a.length-1);
}
private static void sort(Comparable[] a, int lo, int hi){
if (hi <= lo){
return;
}
int mid = lo + (hi-lo)/2;
sort(a, lo, mid); // 將左半邊排序
sort(a, mid+1, hi); // 將右半邊排序
merge(a, lo, mid, hi);
}
private static void merge(Comparable[] a, int lo, int mid, int hi){
int i = lo;
int j = mid + 1;
for (int k=lo; k<=hi; k++){
aux[k] = a[k]; // 將a[lo..hi]複製到aux[lo..hi]
}
for (int k=lo; k<=hi; k++){
if (i > mid){
a[k] = aux[j++];
}else if (j > hi){
a[k] = aux[i++];
}else if (less(aux[j], aux[i])){
a[k] = aux[j++];
}else{
a[k] = aux[i++];
}
}
}
// less() exch() isSorted()和main() 方法見“排序算法類模板”
}
2.2.3 自頂向上的歸併排序
//自頂向上的歸併排序
class MergeBU{
private static Comparable[] aux; // 歸併所需的輔助數組
public static void sort(Comparable[] a){
int N = a.length;
aux = new Comparable[N];
for (int sz=1; sz<N; sz *= 2){
for (int lo=0; lo<N-sz; lo += 2*sz){ //sz子數組大小
merge(a, lo, lo+sz-1, Math.min(lo+2*sz-1, N-1)); //子數組索引
}
}
}
private static void merge(Comparable[] a, int lo, int mid, int hi){
int i = lo;
int j = mid + 1;
for (int k=lo; k<=hi; k++){
aux[k] = a[k]; // 將a[lo..hi]複製到aux[lo..hi]
}
for (int k=lo; k<=hi; k++){
if (i > mid){
a[k] = aux[j++];
}else if (j > hi){
a[k] = aux[i++];
}else if (less(aux[j], aux[i])){
a[k] = aux[j++];
}else{
a[k] = aux[i++];
}
}
}
// less() exch() isSorted()和main() 方法見“排序算法類模板”
}