美文网首页
快速排序思路及实现

快速排序思路及实现

作者: 全狗 | 来源:发表于2020-01-02 21:22 被阅读0次

1、快速排序

同归并排序一样,快排也使用了分治法的思想。不同的是,归并的思路是将两个有序数列合并成一个有序数列,并将该步骤不断的递归下去。而快排的思路是如果数列中的每一个数都比他的左边的所有数都大,比他右边的所有数都小,那么该数列就一定是升序排列的

1.1 步骤描述

分解,将数组A[p...r]分成两个子数组A[p...q-1]A[q+1...r]。使得A[q]大于等于A[p...q-1]的每一个数,同时大于等于A[q+1...r]的每一个数

递归,对子数组A[p...q-1]A[p+1...r]分别执行快排

出口,当子数组大小为1的时候,数组天然有序,此时停止递归,开始回溯

[站外图片上传中...(image-5a283f-1577971358918)]

上图可见,对数列(10,80,30,90,40,50,70)排序.第一次选取70作为中间值,将数列分为L = (10,30,40,50)R = (90,80).后面的以此类推,知道子数组大小为1或者0为止

1.2 伪代码

quickSort(A,p,r):
    if(p < r)
        q = partition(A,p,r);
        quicksort(A,p,q-1)
        quicksort(A,q+1,r)

以上是快排的伪代码,当A.length > 1的时候,即对该数组进行 partition 操作,然后对子数组递归

其中 partition 就是二分数组的方法,返回值为中间值的索引,一下为 partition 的操作描述

partition(A,p,r)
    x = A[r] //选取最后一个值为中间值,以他为标的分割数组
    i= p-1
    for j in (p...r-1)
        if A[j] <= x
            ++i
            交换 A[i] 和 A[j]
    //经过一系列交换后,导致A[i+1]左边的都小于A[r],右边的都大于A[r]
    交换 A[i+1] 和 A[r] 
    // (i+1) 就是A[r]的索引,作为返回值
    return i+1

以上是 partition 操作的伪代码,大致思路就是选取最后一个值为中间值,然后使用两个游标i,j开始遍历数组.i+1左边的都小于A[r],i到j的都是大于A[r]的.最终,j == r-1

1.3 代码实现(Java)

/**
 * @author: luzj
 * @date: 
 * @description: 快排,已测试
 */
public class QuickSort {

    void quickSort(Integer[] A, int p, int r) {
        if (p < r) {
            int q = partition(A, p, r);
            quickSort(A, p, q - 1);
            quickSort(A, q + 1, r);
        }
    }

    private int partition(Integer[] A, int p, int r) {
        Integer x = A[r];
        int i = p - 1;
        for (int j = p; j < r; j++) {
            if (A[j] <= x) {
                i++;
                Integer tmp0 = A[i];
                A[i] = A[j];
                A[j] = tmp0;
            }
        }
        Integer tmp1 = A[i + 1];
        A[i + 1] = A[r];
        A[r] = tmp1;
        return i + 1;
    }

    public static void main(String[] args) {
        Integer[] A = {13,19,9,5,12,8,7,4,21,2,6,11};
        new QuickSort().quickSort(A,0,A.length-1);
        for (int i = 0; i < A.length; i++) {
            System.out.print(A[i]+" ");
        }
    }
}

2、 时间复杂度

快排的时间复杂度依赖于输入的分布,平均情况下快排的时间复杂度为O(nlog(n)).在均衡分割的时候(即A[r]的索引落在数组中间),性能最好.

其实,即使每次数组分割都很不均匀的情况下,比如99:1的比例分割,快排的期望运行时间仍未O(nlog(n)).算法导论的7.4.2部分给出期望运行时间分析。

最坏的情况下,快排的运行时间为O(n^2).当输入为一个有序数列的时候,快排坍缩为插入排序.每一次分叉只能分出一个数组出来,因此无法保证二叉树为对数高度.

3、小结

快排同归并排序一样,使用的是分治法.时间复杂度依赖于输入分布,平均期望运行时间为O(nlog(n))

4、参考

相关文章

  • 快速排序思路及实现

    1、快速排序 同归并排序一样,快排也使用了分治法的思想。不同的是,归并的思路是将两个有序数列合并成一个有序数列,并...

  • 手撕代码 之 快速排序

    1.实现快速排序算法 问题描述给定一个无序数组int[ ] a,使用快速排序算法进行排序。 解题思路对于快速排序,...

  • 2018-05-02 排序算法学习

    排序算法 冒泡排序 实现思路: 两两比较相邻的关键码,如果反序则交换,直到没有反序的记录 快速排序 实现思路: 快...

  • 排序算法(七)快速排序

    排序算法(七)快速排序 1.算法思路  快速排序(Quick-Sort)是从冒泡排序演变而来及基于分而治之思想的排...

  • 接触并理解 快速排序【基础+优化+三向切分】

    要点 算法思想与实现,优化思路,性能分析,三向切分,空间,优势 前言 快速排序之所以被称作“快速”,是因为快速排序...

  • 接触并理解 快速排序【基础+优化+三向切分】

    要点 算法思想与实现,优化思路,性能分析,三向切分,空间,优势 前言 快速排序之所以被称作“快速”,是因为快速排序...

  • 经典排序算法系列5-快速排序

    Quick Sort 快速排序 需求 对N个整数升序排序 思路 和归并排序一样,也是用的分治思想,但实现思路和归并...

  • 【JS编程系列】手写一个快速排序

    一、题目 题目:手写一个快速排序 例子: 二、代码实现 “快速排序”思路: 在数组中,选择一个元素作为“基准”; ...

  • 排序

    八大排序算法 一、归并排序 递归及非递归的JAVA实现 二、快速排序 快排算法JAVA实现 三、堆排序 堆排序堆排...

  • 常用四种排序算法的思想与实现

    无整理 不简书 常用的排序算法有冒泡排序、选择排序、插入排序、快速排序,下面简单介绍四种排序方法的思路与实现代码。...

网友评论

      本文标题:快速排序思路及实现

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