将两个有序的数组归并成一个更大的有序数组,这个操作叫归并。根据这个操作于是就有了归并排序,归并排序有两种实现方式。
自顶向下的归并排序
自顶向下的归并采用了分治(divide-and-conquer)的思想(将问题分(divide)成一些小的问题然后递归求解,然后治(conquer)阶段将分的阶段得到的各答案拼接在一起,即分而治之)。
代码实现
public class Merge {private static Integer[] aux;/*** 初始化辅助数组和相应的上下限数值** @param a* @return*/public static Integer[] sort(Integer[] a) {aux = new Integer[a.length]; // 初始化辅助数组sort(a, 0, a.length - 1);return a;}/*** 辅助函数:用于交换元素** @param valueA* @param valueB* @return*/public static Boolean less(Integer valueA, Integer valueB) {return valueA < valueB;}/*** 辅助函数:用于递归排序** @param a* @param lo* @param hi*/private static void sort(Integer[] a, int lo, int hi) {if (hi <= lo) return; // 极端情况 hi == lo,此时只有一个元素不需要再递归排序。int mid = lo + (hi - lo) / 2;sort(a, lo, mid);sort(a, mid + 1, hi);merge(a, lo, mid, hi); // 合并代码}/*** 将数组中左右已排好序的两边重新合并到一起。** @param a* @param lo* @param mid* @param hi*/public static void merge(Integer[] a, int lo, int mid, int hi) {int i = lo, j = mid + 1;for (int k = lo; k <= hi; k++)aux[k] = a[k];for (int k = lo; k <= hi; k++)if (i > mid) a[k] = aux[j++];else if (j > hi) a[k] = aux[i++];// aux[j] 和 aux[i] 循环两两进行比较,看谁先到达终点,然后执行上面两个分支。else if (less(aux[j], aux[i])) a[k] = aux[j++];else a[k] = aux[i++];}public static void main(String[] args) {Integer[] array1 = new Integer[10];for(int i = 0; i < array1.length; i++) {array1[i] = (int)Math.floor((Math.random() * 10) + 1);}System.out.println(Arrays.toString(array1)); // [7, 5, 3, 8, 6, 3, 1, 10, 6, 9]System.out.println(Arrays.toString(sort(array1))); // [1, 3, 3, 5, 6, 6, 7, 8, 9, 10]}}
自底向上归并排序
实现归并排序的另一种方法是先归并那些微型的数组,然后再成对归并得到子数组,如此这般,直到将整个数组归并在一起。
实现代码
/*** 自低向上归并排序** @param a*/public static Integer[] bUSort(Integer[] a) {int N = a.length;aux = new Integer[N];for (int sz = 1; sz < N; sz = sz + sz) {System.out.println("sz:" + sz);// lo += sz + sz 因为是两两合并所以 sz + sz// 数组长度 N 可能是奇数或者偶数for (int lo = 0; lo < N - sz; lo += sz + sz) {System.out.println(" lo: " + lo);System.out.println(" lo+sz-1: " + (lo + sz - 1));// Math.mi(lo+sz+sz-1, N-1) 兼容数组尾部的两两合并merge(a, lo, lo + sz - 1, Math.min(lo + sz + sz - 1, N - 1));}}return a;}
参考:
