美文网首页
数据结构--快速排序

数据结构--快速排序

作者: Hayley__ | 来源:发表于2020-12-16 11:44 被阅读0次

快速排序 (Quick Sort)

通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

基本思想

1, 从数列中挑出一个元素,称为 “基准”(pivot)。
2, 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
3, 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

示例(Java)

    public static <E extends Comparable<E>> void  sort(E[] arr) {
        Random rnd = new Random();
        sort(arr, 0, arr.length-1, rnd);
    }

    private  static <E extends Comparable<E>> void sort(E[] arr, int l, int r, Random rnd) {
        if (l >= r) return;
        int p = partition(arr, l, r, rnd);
        sort(arr, l, p, rnd);
        sort(arr, p+1, r, rnd);
    }

    //以arr[l]为基准,将<它的值放在它左边,>=等于它的值放在它右边
    private static <E extends Comparable<E>> int partition(E[] arr, int l, int r, Random rnd) {
        //生成[l, r]之间的随机索引
        //优化1 解决如果数组是完全有序数组效率降低的问题,随机选择一个标准值
        int p = l + rnd.nextInt( r - l + 1);
        swap(arr, l , p);

        // arr [l+1...j] < v, arr[j+1...i] >= v
        int j = l;
        for (int i = l +1; i<= r; i++){
            if (arr[i].compareTo(arr[l]) < 0) {
                j ++;
                swap(arr, i, j);
            }
        }
        swap(arr, l , j);
        return j;
    }

    private static <E> void swap(E[] arr, int l, int j) {
        E t = arr[l];
        arr[l] = arr[j];
        arr[j] = t;
    }
思路
逻辑 partition.1
partition.2
partition.3

双路快速排序法:

进一步优化解决,假如数组中有大量相同数据,效率降低的问题

示例(Java)

    //双路快速排序
    //以arr[l]为基准,将<它的值放在它左边, >它的值放在它右边,并交换<=与>= 它的值的位置,使其均匀分布
    private static <E extends Comparable<E>> int partition2(E[] arr, int l, int r, Random rnd) {

        //双路快速排序法
        //优化2 解决如果数组含有大量相同元素
        //生成[l, r]之间的随机索引
        int p = l + rnd.nextInt( r - l + 1);
        swap(arr, l , p);

        int i = l + 1, j = r;

        // arr [l+1...i-1] <= v, arr[j+1...r] >= v
        while (true) {
            while (i <= j && arr[i].compareTo(arr[l]) < 0)
                i ++;
            while (j >= i && arr[j].compareTo(arr[l]) > 0 )
                j --;

            if (i >= j) break;
            swap(arr, i , j);
            i ++;
            j --;
        }

        swap(arr, l , j);
        return j;
    }
partition2.1
partition2.2
partition2.3
partition2.4

三路快速排序法:

进一步优化解决,数组中含有大量相同数据时 与标准值相等的不进行处理,且当数组是完全相同过的时候 复杂度为O(n)

示例(Java)

    //三路快速排序 解决数组中含有大量相同的元素尤其是完全相同数组
    //以arr[l]为基准,将<它的值放在它左边, >它的值放在它右边,=它的值放在中间
    private  static <E extends Comparable<E>> void sort3(E[] arr, int l, int r, Random rnd) {
        if (l >= r) return;

        //随机选择一个标准值
        int p = l + rnd.nextInt(r - l + 1);
        swap(arr, l, p);

        // arr[l+1, lt] < v, arr[lt+1, i-1] == v, arr[gt, r] > v
        int lt = l, i = l + 1, gt = r + 1;

        while (i < gt) {
            if (arr[i].compareTo(arr[l]) < 0) {
                lt ++ ;
                swap(arr, i , lt);
                i ++;
            } else if (arr[i].compareTo(arr[l]) > 0) {
                gt --;
                swap(arr, i, gt);
            } else { // arr[i] == arr[l]
                i ++;
            }
        }
        swap(arr, l , lt);

        // arr[l, lt-1] < v, arr[lt, gt - 1] == v, arr[gt, r] > v
        sort3(arr, l, lt - 1, rnd);
        sort3(arr, gt, r, rnd);
    }
sort3
三路结束条件
最终结果
相同元素时间复杂度
三种方法时间对比

时间复杂度:

平均时间复杂度:O(nlogn)
最佳时间复杂度(三路排序数组中元素完全相同):O(n)
最差时间复杂度(每次选中的随机比较值都是最大或者最小值)(概率极低):O(n^2)
递归深度:O(n)
普通算法:看最差, 能找到一组数据恶化算法
随机算法:看期望, 无法找到一组数据恶化算法


复杂度分析

稳定性

排序前相等的俩个元素,排序后相对位置不变。
不稳定,随机化标定点直接打乱了顺序。

相关文章

  • 排序算法-堆排序

    参考: Java排序算法(五):堆排序 【算法与数据结构】图说堆排序 【数据结构】排序算法:希尔、归并、快速、堆排...

  • 排序算法6:快速排序

    数据结构与算法 快速排序为应用最多的排序算法,因为快速二字而闻名。快速排序和归并排序一样,采用的都是分治思想。 分...

  • Python 算法大全

    这个库涵盖了多种算法和数据结构的介绍,比如: 排序算法(冒泡排序、希尔排序、插入排序、桶排序、合并排序、快速排序、...

  • C语言:关于数据的几种排序算法

    数据结构的排序算法有很多种。其中,快速排序、希尔排序、堆排序、直接选择排序不是稳定的排序算法;基数排序、冒泡排序、...

  • 数据结构与算法——快速排序

    数据结构与算法——快速排序 快速排序,顾名思义,它速度很快,针对一般应用中各种不同的输入都要比其他排序算法快很多,...

  • 排序算法-快速排序

    数据结构 排序算法 快速排序 快速排序的做法是通过找到一个枢纽(pivot),这个枢纽可以将数组划分为两部分,一部...

  • 玩转算法面试:(三)LeetCode数组类问题

    数组中的问题其实最常见。 排序:选择排序;插入排序;归并排序;快速排序查找:二分查找法数据结构:栈;队列;堆…… ...

  • 算法(3)- 数组

    数组中的问题其实最常见如:排序(选择排序、插入排序、归并排序、快速排序)、查找(二分查找法)、数据结构(栈、队列、...

  • 算法与数据结构路线图

    学习算法与数据结构,深刻理解计算机科学 排序算法:插入、冒泡、选择、希尔、快速、归并、堆排序、计数排序、桶排序、基...

  • 排序算法

    常考排序 快速排序 归并排序 归并排序求逆序数对 堆排序 堆排序是指利用堆这种数据结构所设计的一种排序算法。 堆积...

网友评论

      本文标题:数据结构--快速排序

      本文链接:https://www.haomeiwen.com/subject/hyevgktx.html