question:
Median-of 3 partitioning. Add median-of-3 partitioning to quicksort, as described in the text (see page 296). Run doubling tests to determine the effectivemess of the change.
answer:
//三取样切分
//顺便用三个值中的最大值做哨兵
import edu.princeton.cs.algs4.*; public class Quicksort { public static void sort(Comparable[] a) { StdRandom.shuffle(a); sort(a, 0, a.length - 1); } private static void sort(Comparable[] a, int lo, int hi) { if(hi <= lo) return; int j = partition(a, lo, hi); sort(a, lo, j-1); sort(a, j+1, hi); } private static int partition(Comparable[] a, int lo, int hi) { int i = lo, j = hi+1; int mid = lo + (hi-lo)/2; int pos = MedianOfThree(a,lo,mid,hi);//返回中值的位置 exch(a,lo,pos);//交换中值和lo处的值 int sentinel = less(a[pos],a[hi]) ? hi : pos;//找三个值中最大的作为哨兵 exch(a, sentinel, hi); Comparable v = a[lo]; while(true) { while(less(a[++i], v)); while(less(v,a[--j])); if(i >= j) break; exch(a, i, j); } exch(a, lo, j); return j; } public static int MedianOfThree(Comparable[] a, int lo, int mid, int hi)//返回三个位置处的中值的位置 { return (less(a[lo], a[mid]) ? (less(a[mid], a[hi]) ? mid : less(a[lo], a[hi]) ? hi : lo) : (less(a[hi], a[mid]) ? mid : less(a[hi], a[lo]) ? hi : lo)); } private static boolean less(Comparable v, Comparable w) { return v.compareTo(w) < 0; } private static void exch(Comparable[] a, int i, int j) { Comparable t = a[i]; a[i] = a[j]; a[j] = t; } 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 main(String[] args) { String[] a = In.readStrings(); sort(a); assert isSorted(a); show(a); } }