zoukankan      html  css  js  c++  java
  • 算法(Algorithms)第4版 练习 2.3.17

    关键代码:

      public static void sort(Comparable[] a) {
            StdRandom.shuffle(a);//eliminate dependence on input
            StdOut.print("After shuffle:");//for test
            show(a);//for test
            int largest = largest(a);
            exch(a, largest, a.length - 1);
            StdOut.print("After find largest and exchange:");//for test
            show(a);//for test
            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;
            int j = hi + 1;
            Comparable v = a[lo];
            
            StdOut.println();//for test
            StdOut.printf("partition(input, %4d, %4d)
    ", lo, hi);//for test
            
            while(true) {
                
                while(less(a[++i], v));//find item larger or equal to v
                while(less(v, a[--j]));//not need to worry about j will be out of bound
                
                StdOut.println("i:" + i + " j:" + j);//for test
                
                if(i >= j)//cross
                    break;
                
                exch(a, i, j);
                show(a);//for test
            }
            exch(a, lo, j);
            
            StdOut.printf("j is %4d
    ", j);//for test
            show(a);//for test
            
            return j;
            
        }

    测试用例:

    package com.qiusongde;
    
    import edu.princeton.cs.algs4.In;
    import edu.princeton.cs.algs4.StdOut;
    import edu.princeton.cs.algs4.StdRandom;
    
    public class QuickSentinel {
    
        public static void sort(Comparable[] a) {
            StdRandom.shuffle(a);//eliminate dependence on input
            StdOut.print("After shuffle:");//for test
            show(a);//for test
            int largest = largest(a);//find largest item
            exch(a, largest, a.length - 1);//set sentinel in right bound
            StdOut.print("After find largest and exchange:");//for test
            show(a);//for test
            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;
            int j = hi + 1;
            Comparable v = a[lo];
            
            StdOut.println();//for test
            StdOut.printf("partition(input, %4d, %4d)
    ", lo, hi);//for test
            
            while(true) {
                
                while(less(a[++i], v));//find item larger or equal to v
                while(less(v, a[--j]));//not need to worry about j will be out of bound
                
                StdOut.println("i:" + i + " j:" + j);//for test
                
                if(i >= j)//cross
                    break;
                
                exch(a, i, j);
                show(a);//for test
            }
            exch(a, lo, j);
            
            StdOut.printf("j is %4d
    ", j);//for test
            show(a);//for test
            
            return j;
            
        }
        
        private static void exch(Comparable[] a, int i, int j) {
            
            Comparable t = a[i];
            a[i] = a[j];
            a[j] = t;
            
        }
        
        private static int largest(Comparable[] a) {
            assert a != null;
            assert a.length > 1;
            
            int largestindex = 0;
            for(int i = 1; i < a.length; i++) {
                if(less(a[largestindex], a[i]))
                    largestindex = i;
            }
            
            return largestindex;
        }
        
        private static boolean less(Comparable v, Comparable w) {
            
            return v.compareTo(w) < 0;
            
        }
        
        private static void show(Comparable[] a) {
            
            //print the array, on a single line.
            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) {
            //Read strings from standard input, sort them, and print.
            String[] a = In.readStrings();
            show(a);
            sort(a);
            assert isSorted(a);
            show(a);
        }
        
    }

    输出结果:

    红色部分可看到右子数组的最左元素可作为左子数组右边界的哨兵。

    K R A T E L E P U I M Q C X O S 
    After shuffle:E S I X E T P K C O R Q L U M A 
    After find largest and exchange:E S I A E T P K C O R Q L U M X 
    
    partition(input,    0,   15)
    i:1 j:8
    E C I A E T P K S O R Q L U M X 
    i:2 j:4
    E C E A I T P K S O R Q L U M X 
    i:4 j:3
    j is    3
    A C E E I T P K S O R Q L U M X 
    
    partition(input,    0,    2)
    i:1 j:0
    j is    0
    A C E E I T P K S O R Q L U M X 
    
    partition(input,    1,    2)
    i:2 j:1
    j is    1
    A C E E I T P K S O R Q L U M X 
    
    partition(input,    4,   15)
    i:5 j:4
    j is    4
    A C E E I T P K S O R Q L U M X 
    
    partition(input,    5,   15)
    i:13 j:14
    A C E E I T P K S O R Q L M U X 
    i:14 j:13
    j is   13
    A C E E I M P K S O R Q L T U X 
    
    partition(input,    5,   12)
    i:6 j:12
    A C E E I M L K S O R Q P T U X 
    i:8 j:7
    j is    7
    A C E E I K L M S O R Q P T U X 
    
    partition(input,    5,    6)
    i:6 j:5
    j is    5
    A C E E I K L M S O R Q P T U X 
    
    partition(input,    8,   12)
    i:13 j:12
    j is   12
    A C E E I K L M P O R Q S T U X 
    
    partition(input,    8,   11)
    i:10 j:9
    j is    9
    A C E E I K L M O P R Q S T U X 
    
    partition(input,   10,   11)
    i:12 j:11
    j is   11
    A C E E I K L M O P Q R S T U X 
    
    partition(input,   14,   15)
    i:15 j:14
    j is   14
    A C E E I K L M O P Q R S T U X 
    A C E E I K L M O P Q R S T U X 

    性能对比:

    For 2000 random Doubles 10000 trials
    Quick is 2.3s QuickSentinel is 2.3s

    没有大区别。

  • 相关阅读:
    压缩与解压缩 ZipHelper
    ESFramework介绍之(15)-- IRAS
    ESFramework介绍之(8)-- 客户端插件IPassiveAddin
    使用Eclipse开发Jsp
    深入探讨 java.lang.ref 包
    java多线程总结二
    模拟弹子台球java多线程应用
    简单的邮件客户端
    最近创办了一个java学习邮件列表
    优秀的XML~~Altova XMLSpy 2010英文企业版+有效破解方法
  • 原文地址:https://www.cnblogs.com/songdechiu/p/6634494.html
Copyright © 2011-2022 走看看