1.归并排序最吸引人的性质是它能够保证将任意长度为N的数组排序所需时间和NlogN成正比;它的主要缺点则是它所需的额外空间和N成正比。
2.对于长度为N的任意数组,自顶向下的归并排序需要1/2NlogN至NlogN次比较。
3.对于长度为N的任意数组,自顶向下的归并排序最多需要访问数组6NlogN次。
4.使用插入排序处理小规模的子数组(比如长度小于15)一般可以将归并排序的运行时间缩短10%~15%。
5.对于长度为N的任意数组,自底向上的归并排序需要1/2NlogN至NlogN次比较,最多访问数组6NlogN次。
6.当数组长度为2的幂时,自顶向下和自底向上的归并排序所用的比较次数和数组访问次数正好相同,只是顺序不同。其他时候,两种方法的比较和数组访问数组的次序会有所不同。
7.自底向上的归并排序比较适合用链表组织的数据。
8.归并排序是一种渐进最优的基于比较排序的算法。
9.自顶向下的归并排序:
1 public class Merge { 2 private static Comparable[] aux; 3 public static void sort(Comparable[] a) 4 { 5 aux = new Comparable[a.length]; 6 sort(a, 0, a.length - 1); 7 } 8 9 private static void sort(Comparable[] a, int lo, int hi) 10 { 11 if (hi <= lo) return; 12 int mid = lo + (hi -lo)/2; 13 sort(a, lo, mid); 14 sort(a, mid, hi); 15 merge(a, lo, mid, hi); 16 } 17 18 public static void merge(Comparable[] a, int lo, int mid, int hi) 19 { 20 int i = lo; 21 int j = mid + 1; 22 for (int k = lo; k <= hi; k++) 23 aux[k] = a[k]; 24 for (int k = lo; k <= hi; k++) 25 { 26 if (i > mid) a[k] = aux[j++]; 27 else if (j > hi) a[k] = aux[i++]; 28 else if (aux[j].compareTo(aux[i]) < 0) a[k] = aux[j++]; 29 else a[k] = aux[i++]; 30 } 31 32 } 33 }
10.自底向上的归并排序:
1 public class MergeBU { 2 private static Comparable[] aux; 3 public static void sort(Comparable[] a) 4 { 5 int N = a.length; 6 aux = new Comparable[N]; 7 for (int sz = 1; sz < N; sz = sz + sz) 8 for (int lo = 0; lo < N - sz; lo += sz + sz) 9 merge (a, lo, lo + sz -1, Math.min(lo+sz+sz-1, N-1)); 10 } 11 public static void merge(Comparable[] a, int lo, int mid, int hi) 12 { 13 int i = lo; 14 int j = mid + 1; 15 for (int k = lo; k <= hi; k++) 16 aux[k] = a[k]; 17 for (int k = lo; k <= hi; k++) 18 { 19 if (i > mid) a[k] = aux[j++]; 20 else if (j > hi) a[k] = aux[i++]; 21 else if (aux[j].compareTo(aux[i]) < 0) a[k] = aux[j++]; 22 else a[k] = aux[i++]; 23 } 24 } 25 }