2.3.17

question:

Sentinels. Modify the code in ALGORITHM 2.5 to remove both bounds checks in the inner while loops. The test against the left end of the subarray is redundant since the partitioning item acts as a sentinel (v is never less than a[lo]). To enable removal of the other test, put an item whose key is the largest in the whole array into a[length-1] just after the shuffle. This item will never move (except possibly to be swapped with an item having the same key) and will serve as a sentinel in all subarrays involving the end of the array. Note: When sorting interior subarrays, the leftmost entry in the subarray to the right serves as a sentinel for the right end of the subarray.

answer:

//原本以为子数组的边界会很麻烦,其实你跟一遍循环就知道那些都不用考虑的

//所以只要在打乱后把最大的元素放到最后就行了,也不用担心它会被交换走,因为那是不可能的(题目中已解释)

import edu.princeton.cs.algs4.*;

public class Quicksort
{
    public static void sort(Comparable[] a)
    {
        StdRandom.shuffle(a);
        for(int i = 1; i < a.length; i++)//右侧哨兵
        {
            if(less(a[i],a[i-1]))
                exch(a,i,i-1);
        }
        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;
        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;
    }
    
    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);
    }
}

猜你喜欢

转载自www.cnblogs.com/w-j-c/p/9130638.html