归并排序的算法思想是:设 r[u…t] 由两个有序子表 r[u…v-1] 和 r[v…t] 组成,两
个子表长度分别为 v-u、t-v+1
代码示意图如下:
public class MergeSort {
/**
* 时间复杂度 nlogn
* @param a 原数组
* @param swap 中间数据,存放归并元素
* @param k 归并长度 ,1
*/
public void merge(int[] a, int[] swap, int k) {
int n = a.length;
// u1 第二个有序子数组下界,
int m = 0, u1, l2, i, j, u2;
int l1 = 0;
//第一个有序子数组下界为0
// 这个while循环是将两组两组的进行归并
while (l1 + k <= n - 1) {
l2 = l1 + k;
//计算第二个有序子数组下界
u1 = l2 - 1;
//计算第一个有序子数组上界
u2 = (l2 + k - 1 <= n - 1) ? l2 + k - 1 : n - 1;// 计算第二个有序子数组上界
for (i = l1, j = l2; i <= u1 && j <= u2; m++) {
// 把较小值放入临时数组,直到结束
if (a[i] <= a[j]) {
swap[m] = a[i];
i++;
} else {
swap[m] = a[j];
j++;
}
}
// 子数组 2 已归并完,将子数组 1 中剩余的元素存放到数组 swap 中
while (i <= u1) {
swap[m] = a[i];
m++;
i++;
}
// 子数组 1 已归并完,将子数组 2 中剩余的元素存放到数组 swap 中
while (j <= u2) {
swap[m] = a[j];
m++;
j++;
}
l1 = u2 + 1;
}
// 将原始数组中只够一组的数据元素顺序存放到数组 swap 中
for (i = l1; i < n; i++, m++)
swap[m] = a[i];
}
/**
* 归并
* @param a
*/
public void mergeSort(int[] a) {
int i;
int n = a.length;
int k = 1;// 归并长度从 1 开始
int[] swap = new int[n];
while (k < n) {
merge(a, swap, k);
// 调用函数 merge()
for (i = 0; i < n; i++)
a[i] = swap[i]; // 将元素从临时数组 swap 放回数组 a 中
k = 2 * k; // 归并长度加倍
}
}
public static void main(String[] args) {
int[] test = {16, 15, 19, 16, 18, 19, 20, 14};
MergeSort ss = new MergeSort();
ss.mergeSort(test);
for (int i = 0; i < test.length; i++)
System.out.print(test[i] + " ");
}
}