zoukankan      html  css  js  c++  java
  • 算法(第4版)-2.3 快速排序

    public class Quick {
        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);                        // 将左半部分a[lo..j-1]排序
            sort(a, j + 1, hi);                        // 将右半部分a[j+1..hi]排序
        }
    
        private static int partition(Comparable[] a, int lo, int hi) {
            // 将数组切分为a[lo..i-1],a[i],a[i+1..hi]
            int i = lo, j = hi + 1;                // 左右扫描指针
            Comparable v = a[lo];                    // 切分元素
            while (true) {
                // 扫描左右,检查扫描是否结束并交换元素
                while (less(a[++i], v))    if (i == hi)    break;
                while (less(v, a[--j]))    if (j == lo)    break;
                if (i >= j)    break;
                exch(a, i, j);
            }
            exch(a, lo, j);    // 将v = a[j]放入正确的位置
            return j;                // a[lo..j-1] <= a[j] <= a[j+1..hi]达成
        }
    
        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);
        }
    }
    Quick

    主要优点:

    · 实现简单

    · 适用于各种不同的输入数据

    · 在一般应用中比其他排序算法都要快得多

    主要缺点:

    · 非常脆弱

    2.3.1 基本算法

    1. 我们就是通过递归的调用切分来排序的。

    2. 需要注意以下几点:

    · 原地切分

    · 别越界

    · 保持随机性

    · 终止循环

    · 处理切分元素值有重复的情况

    · 终止递归

    2.3.2 性能特点

    1. 快速排序的最好情况是每次都正好能将数组对半分。

    2. 将长度为N的无重复数组排序,快速排序平均需要~2NlnN次比较(以及1/6的交换)。

    3. 快速排序最多需要约n^2/2次比较,但随机打乱数组能够预防这种情况。

    2.3.3 算法改进

    1. 切换到插入排序

    小型数组由插入排序来完成

    2. 三取样切分

    3. 熵最优的排序

    -> 三向切分的快速排序

    public class Quick3way {
        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 lt = lo, i = lo + 1, gt = hi;
            Comparable v = a[lo];
            while (i <= gt) {
                int cmp = a[i].compareTo(v);
                if             (cmp < 0)    exch(a, lt++, i++);
                else if (cmp > 0)    exch(a, i, gt--);
                else                            i++;
            }    // 现在 a[lo..lt-1] < v = a[lt..gt] < a[gt+1..hi]成立
            sort(a, lo, lt - 1);
            sort(a, gt + 1, hi);
        }
    
        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);
        }
    }
    Quick3way

    · 对于存在大量重复元素的数组,这种方法比标准的快速排序的效率高得多。

  • 相关阅读:
    c++11——列表初始化
    flask学习(十二):for循环遍历
    flask学习(十一):if判断语句
    flask学习(十):模板中访问模型和字典的属性
    flask学习(九):模板渲染和参数传递
    flask学习(八):页面跳转和重定向
    flask学习(七):URL反转
    flask学习(六):URL传参
    flask学习(五):使用配置文件
    flask学习(四):debug模式
  • 原文地址:https://www.cnblogs.com/iguure/p/6105848.html
Copyright © 2011-2022 走看看