归并排序 O(N*logN)
用递归方法将排好序的半子表合并成为越来越大的有序序列,
归并排序将两个已排序的表合并成一个表。
采用先 “分割” 再 “合并” 的思想,我们首先把一个未排序的序列从中间分割成2部分,再把2部分分成4部分,依次分割下去,直到分割成一个一个的数据,再把这些数据两两归并到一起,使之有序,不停的归并,最后成为一个排好序的序列。
因为归并排序每次都是在相邻的数据中进行操作,所以归并排序在O(N*logN)的几种排序方法(快速排序,归并排序,希尔排序,堆排序)也是效率比较高的。
归并排序是一种稳定的排序。
public class MergeSort {
public static void main(String[] args) {
int[] array = { 6, 3, 7, 2 };
InversePairs(array);
}
public static void InversePairs(int[] array) {
if (array != null) {
mergeSortUp2Down(array, 0, array.length - 1);
}
}
/*
* 归并排序(从上往下)
*/
public static void mergeSortUp2Down(int[] a, int start, int end) {
if (start >= end) {
return;
}
int mid = (start + end) >> 1;
mergeSortUp2Down(a, start, mid);
mergeSortUp2Down(a, mid + 1, end);
merge(a, start, mid, end);
}
/*
* 将一个数组中的两个相邻有序区间合并成一个
*/
public static void merge(int[] a, int start, int mid, int end) {
int[] tmp = new int[end - start + 1];
// i
int i = start;
int j = mid + 1;
int k = 0;
// 防止越界
while (i <= mid && j <= end) {
if (a[i] <= a[j]) {
tmp[k++] = a[i++];
} else {
tmp[k++] = a[j++];
}
}
// 把剩余本来有序的数据添加到临时数组
while (i <= mid) {
tmp[k++] = a[i++];
}
while (j <= end) {
tmp[k++] = a[j++];
}
// 然后把排好序的临时数组覆盖原始无序数组
for (k = 0; k < tmp.length; k++) {
a[start + k] = tmp[k];
}
}
}