Merge Sort
典型的分治法思想算法,Divide and Conquer.divide-and-conquer将问题(original problem)分拆成规模比原来小,性质和原来相似的小问题(subproblems).最后,合并小问题解决的结果。
由于这是一种典型的递归算法,每拆分一次,问题规模必须变得更小,而且要有最小的可解的小问题,即base case for subproblems.
Divide the problem into a number of subproblems that are smaller instances of the same problem.
Conquer the subproblems by solving them recursively. If they are small enough, solve the subproblems as base cases.
Combine the solutions to the subproblems into the solution for the original problem.
归并排序的整个大问题:排序序列array[low到high]
小问题:排序子序列,array[low到mid],array[mid+1到high]
merge sort divide-and-conquer:
- Divide:寻找low与high之间的中间数,就像二分查找那样,分出两个子序列
- Conquer:对每个由Divide步骤分出的小问题,递归排序array[low到mid],array[mid+1到high]
Combine:合并子序列
递归的条件,若只有0或1个元素,即low>=high,不用排序了。所以,只有low
public class MergeSort {
public static void mergeSort(int[] array) {
merge_sort(array, 0, array.length - 1);
}
private static int[] merge_sort(int[] array, int low, int high) {
int mid;
if (low < high) {
mid = (low + high) >>> 1;
merge_sort(array, low, mid);
merge_sort(array, mid + 1, high);
merge(array, low, high, mid);
}
return array;
}
/**
* linear runtime to merge
*/
private static void merge(int[] array, int low, int high, int mid) {
int[] lowHalf = new int[mid - low + 1];
int[] highHalf = new int[high - mid];
// pointer to array
int k = low;
// pointers to sub arrays
int i, j;
for (i = 0; k <= mid; i++, k++) {
lowHalf[i] = array[k];
}
for (j = 0; k <= high; j++, k++) {
highHalf[j] = array[k];
}
k = low;
i = 0;
j = 0;
// Repeatedly compare the lowest untaken element in
// lowHalf with the lowest untaken element in highHalf
// and copy the lower of the two back into array
while ((i < lowHalf.length) && (j < highHalf.length)) {
if (lowHalf[i] < highHalf[j]) {
array[k++] = lowHalf[i++];
} else {
array[k++] = highHalf[j++];
}
}
// Once one of lowHalf and highHalf has been fully copied
// back into array, copy the remaining elements from the
// other temporary array back into the array
while (i < lowHalf.length) {
array[k++] = lowHalf[i++];
}
while (i < highHalf.length) {
array[k++] = highHalf[j++];
}
//clear int[] Object, let GC collects them
lowHalf = null;
highHalf = null;
}
public static void main(String[] args) {
int[] b = { 12, 6, 8, 3, 16, 22, 9, 14, 2, 17 };
mergeSort(b);
for (int i : b) {
System.out.print(i + " ");
}
}
}