question:
Improvements. Implement the three improvements to merge sort that are described in the text on page 275: Add a cutoff for small subarrays, test whether the array is already in order, and avoid the copy by switching arguments in the recurisive code.
answer:
//对归并排序进行三处优化
import edu.princeton.cs.algs4.*; public class Merge { public static void sort(Comparable[] a) { Comparable[] b = new Comparable[a.length]; sort(a, b, 0, a.length-1); } private static boolean less(Comparable v, Comparable w) { return v.compareTo(w) < 0; } private static void show(Comparable[] a) { for(int i = 0; i < a.length; i++) StdOut.print(a[i] + " "); StdOut.println(); } public static boolean isSorted(Comparable[] a) { for(int i = 1; i < a.length; i++) if(less(a[i], a[i-1])) return false; return true; } public static void merge(Comparable[] a, Comparable[] b, int lo, int mid, int hi)//传两个数组用于对掉原来的a和aux { //这里直接把a[]归并到b[]里面,然后把b当成a int i = lo, j = mid + 1; for(int k = lo; k <= hi; k++)//其实这里还可以用上题2.2.10来优化,这题没要求我就没改了,可参见上题 { if(i > mid) b[k] = a[j++]; else if(j > hi) b[k] = a[i++]; else if(less(a[i], a[j])) b[k] = a[i++]; else b[k] = a[j++]; } } private static void sort(Comparable[] a, Comparable[] b, int lo, int hi)//传两个数组用于对掉原来的a和aux { //优化3,主要就是这里sort,和merge参数的互换减少了原来归并里复制a到aux里 if(a.length <= 15)//优化1,数组过小则用插入排序 { Selection.sort(a); return; } if(hi <= lo) return; int mid = lo + (hi - lo) / 2; sort(b,a,lo,mid);//这里就是把b当成a sort(b,a,mid+1,hi);//这里也是把b当成a if(!(a[mid].compareTo(a[mid+1])<0))//优化2,测试数组是否已经有序 merge(a,b,lo,mid,hi);//归并a } public static void main(String[] args) { String[] a = In.readStrings(); sort(a); assert isSorted(a); show(a); } }