主要思想:先将数组分成两半,分别对两半进行排序,然后将结果归并起来。对两半的排序也是如此。
package algorithms.ch2;
public class Merge {
private static Comparable[] aux;
/**
* 归并
* 左半部分 left - mid 有半部分 mid+1 - right
* @param a
* @param left
* @param mid
* @param right
*/
public static void merge(Comparable[] a, int left, int mid, int right){
for(int i = left; i <= right; i++){
aux[i] = a[i];
}
// int i = left;
// int j = mid+1;
// int k = left;
// while(i <= mid && j <= right){
// if(less(aux[i], aux[j])){
// a[k++] = aux[i++];
// } else {
// a[k++] = aux[j++];
// }
// }
// while(i <= mid){
// a[k++] = aux[i++]; //左半部分遍历结束,将右半部分复制到a中
// }
// while(j <= right){
// a[k++] = aux[j++]; //右半部分遍历结束,将左半部分复制到a中
// }
int i = left; int j = mid+1;
for(int k = left; k <= right; k++){
if(i > mid){
a[k] = aux[j++]; //左半部分遍历结束,将右半部分复制到a中
} else if(j > right){
a[k] = aux[i++]; //右半部分遍历结束,将左半部分复制到a中
} else if(less(a[i], a[j])){
a[k] = aux[i++];
} else {
a[k] = aux[j++];
}
}
}
public static void sort(Comparable[] a){
aux = new Comparable[a.length];
sort(a, 0, a.length-1);
}
public static void sort(Comparable[] a, int left, int right){
if(right <= left){
return;
}
int mid = (left + right)/2;
sort(a, left, mid); //归并左半部分
sort(a, mid+1, right); //归并右半部分
merge(a, left, mid, right);
}
/**
* v < w 返回true
* @param v
* @param w
* @return
*/
public static boolean less(Comparable v, Comparable w){
return v.compareTo(w) < 0;
}
private static void exch(Comparable[] a, int i, int j){
Comparable t = a[i];
a[i] = a[j];
a[j] = t;
}
private static void show(Comparable[] a){
for(int i = 0; i < a.length; i++){
System.out.print(a[i] + " ");
}
System.out.println();
}
public static boolean isSorted(Comparable[] a){
for(int i = 1; i < a.length; i++){
if(less(a[i], a[i-1])) return false;
}
return true;
}
public static void main(String[] args){
String[] a = {"S", "O", "R", "T", "E", "X", "A", "M", "P", "L", "E"};
sort(a);
assert isSorted(a);
show(a);
}
}
本文为归并排序的一些自己的理解与编程代码。