0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

快速排序是一种交换排序

算法与数据结构 来源:未知 作者:李倩 2018-07-27 14:49 次阅读

要点

快速排序是一种交换排序。

快速排序由C. A. R. Hoare在1962年提出。

它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分:分割点左边都是比它小的数,右边都是比它大的数。

然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

详细的图解往往比大堆的文字更有说明力,所以直接上图:

上图中,演示了快速排序的处理过程:

初始状态为一组无序的数组:2、4、5、1、3。

经过以上操作步骤后,完成了第一次的排序,得到新的数组:1、2、5、4、3。

新的数组中,以2为分割点,左边都是比2小的数,右边都是比2大的数。

因为2已经在数组中找到了合适的位置,所以不用再动。

2左边的数组只有一个元素1,所以显然不用再排序,位置也被确定。(注:这种情况时,left指针和right指针显然是重合的。因此在代码中,我们可以通过设置判定条件left必须小于right,如果不满足,则不用排序了)。

而对于2右边的数组5、4、3,设置left指向5,right指向3,开始继续重复图中的一、二、三、四步骤,对新的数组进行排序。

核心代码

publicintdivision(int[]list,intleft,intright){//以最左边的数(left)为基准intbase=list[left];while(left< right) {        // 从序列右端开始,向左遍历,直到找到小于base的数        while (left < right && list[right] >=base)right--;//找到了比base小的元素,将这个元素放到最左边的位置list[left]=list[right];//从序列左端开始,向右遍历,直到找到大于base的数while(left< right && list[left] <= base)            left++;        // 找到了比base大的元素,将这个元素放到最右边的位置        list[right] = list[left];    }    // 最后将base放到left位置。此时,left位置的左侧数值应该都比left小;    // 而left位置的右侧数值应该都比left大。    list[left] = base;    return left;}private void quickSort(int[] list, int left, int right) {    // 左下标一定小于右下标,否则就越界了    if (left < right) {        // 对数组进行分割,取出下次分割的基准标号        int base = division(list, left, right);        System.out.format("base = %d:", list[base]);        printPart(list, left, right);        // 对“基准标号“左侧的一组数值进行递归的切割,以至于将这些数值完整的排序        quickSort(list, left, base - 1);        // 对“基准标号“右侧的一组数值进行递归的切割,以至于将这些数值完整的排序        quickSort(list, base + 1, right);    }}算法分析

快速排序算法的性能

时间复杂度

当数据有序时,以第一个关键字为基准分为两个子序列,前一个子序列为空,此时执行效率最差。

而当数据随机分布时,以第一个关键字为基准分为两个子序列,两个子序列的元素个数接近相等,此时执行效率最好。

所以,数据越随机分布时,快速排序性能越好;数据越接近有序,快速排序性能越差。

空间复杂度

快速排序在每次分割的过程中,需要 1 个空间存储基准值。而快速排序的大概需要 Nlog2N次的分割处理,所以占用空间也是 Nlog2N 个。

算法稳定性

在快速排序中,相等元素可能会因为分区而交换顺序,所以它是不稳定的算法。

完整参考代码

JAVA版本

代码实现

1publicclassQuickSort{23publicintdivision(int[]list,intleft,intright){4//以最左边的数(left)为基准5intbase=list[left];6while(left< right) { 7             // 从序列右端开始,向左遍历,直到找到小于base的数 8             while (left < right && list[right] >=base)9right--;10//找到了比base小的元素,将这个元素放到最左边的位置11list[left]=list[right];1213//从序列左端开始,向右遍历,直到找到大于base的数14while(left< right && list[left] <= base)15                 left++;16             // 找到了比base大的元素,将这个元素放到最右边的位置17             list[right] = list[left];18         }19  20         // 最后将base放到left位置。此时,left位置的左侧数值应该都比left小;21         // 而left位置的右侧数值应该都比left大。22         list[left] = base;23         return left;24     }25  26     private void quickSort(int[] list, int left, int right) {27  28         // 左下标一定小于右下标,否则就越界了29         if (left < right) {30             // 对数组进行分割,取出下次分割的基准标号31             int base = division(list, left, right);32  33             System.out.format("base = %d:", list[base]);34             printPart(list, left, right);35  36             // 对“基准标号“左侧的一组数值进行递归的切割,以至于将这些数值完整的排序37             quickSort(list, left, base - 1);38  39             // 对“基准标号“右侧的一组数值进行递归的切割,以至于将这些数值完整的排序40             quickSort(list, base + 1, right);41         }42     }43  44     // 打印序列45     public void printPart(int[] list, int begin, int end) {46         for (int i = 0; i < begin; i++) {47             System.out.print("");48         }49         for (int i = begin; i <= end; i++) {50             System.out.print(list[i] + "");51         }52         System.out.println();53     }54  55     public static void main(String[] args) {56         // 初始化一个序列57         int[] array = {58                 1, 3, 4, 5, 2, 6, 9, 7, 8, 059         };60  61         // 调用快速排序方法62         QuickSort quick = new QuickSort();63         System.out.print("排序前:");64         quick.printPart(array, 0, array.length - 1);65         quick.quickSort(array, 0, array.length - 1);66         System.out.print("排序后:");67         quick.printPart(array, 0, array.length - 1);68     }69 }

运行结果

排序前: 1 3 4 5 2 6 9 7 8 0 base = 1: 0 1 4 5 2 6 9 7 8 3 base = 4: 3 2 4 6 9 7 8 5 base = 3: 2 3 base = 6: 5 6 7 8 9 base = 7: 7 8 9 base = 8: 8 9 排序后: 0 1 2 3 4 5 6 7 8 9

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 算法
    +关注

    关注

    23

    文章

    4451

    浏览量

    90742
  • 快速排序
    +关注

    关注

    0

    文章

    3

    浏览量

    5411

原文标题:排序算法总结(2):快速排序

文章出处:【微信号:TheAlgorithm,微信公众号:算法与数据结构】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    FPGA排序-冒泡排序介绍

    排序算法是图像处理中经常使用一种算法,常见的排序算法有插入排序、希尔排序、选择排序、冒泡
    发表于 07-17 10:12 661次阅读
    FPGA<b class='flag-5'>排序</b>-冒泡<b class='flag-5'>排序</b>介绍

    常用排序法详解总结和比较选择

    ,并且不会出现快速排序可能出现的最坏情况。这两排序都是不稳定的。  若要求排序稳定,则可选用归并排序
    发表于 10-26 15:11

    快速排序

    // 快速排序package algorithmsimport "fmt"// 第一种写法func quickSort(values []int, left, right int
    发表于 10-17 19:05

    常用排序法之 ——冒泡排序法和选择排序

    语言中,常用的算法有:冒泡排序快速排序、插入排序、选择排序、希尔排序、堆
    发表于 11-01 12:25

    简述计算机排序

    不用交换,低指针指向的小于枢轴的元素不用交换。直到高低指针指向小于等于或者大于等于的元素后直接交换元素。趟过后,在低子分区和高子分区中继续进行递归
    发表于 12-26 23:07

    嵌入式stm32实用的排序算法 - 交换排序

    :插入排序、选择排序交换排序、归并排序、基数排序排序的分类大致为如下图:在内部
    发表于 04-12 13:14

    C#实现快速排序

    快速排序法是对冒泡排序一种改进。它的基本思想是,通过一趟排序将待排序记录分割成独立的两部分,其
    发表于 08-09 17:57 16次下载

    一文了解冒泡排序

    冒泡排序一种交换排序。 什么是交换排序呢? 交换排序:两两比较待排序的关键字,并
    的头像 发表于 01-17 12:47 2853次阅读
    一文了解冒泡<b class='flag-5'>排序</b>

    常用排序算法分析

    一种是比较排序,时间复杂度O(nlogn) ~ O(n^2),主要有:冒泡排序,选择排序,插入排序,归并
    的头像 发表于 07-13 16:13 1959次阅读

    实用的排序算法 - 交换排序

    实用的排序算法 - 交换排序
    的头像 发表于 03-20 09:53 1557次阅读
    实用的<b class='flag-5'>排序</b>算法 -  <b class='flag-5'>交换排序</b>

    揭秘冒泡排序交换排序和插入排序

    一个教官对这支队伍进行整理,使得队伍里的人从低到高的排下去,教官想到了一种排序算法来对这支队伍进行身高排序。 如何理解冒泡排序 教官立马想到了一个
    的头像 发表于 06-18 09:57 1305次阅读

    C语言排序快速排序的技巧

    快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,
    的头像 发表于 07-29 15:14 2267次阅读
    C语言<b class='flag-5'>排序</b>中<b class='flag-5'>快速</b><b class='flag-5'>排序</b>的技巧

    冒泡排序的基本思想

    冒泡排序的英文Bubble Sort,是一种最基础的交换排序。之所以叫做冒泡排序,因为每一个元素都可以像小气泡一样,根据自身大小一点一点向数组的一侧移动。
    的头像 发表于 01-20 11:38 5200次阅读
    冒泡<b class='flag-5'>排序</b>的基本思想

    php版冒泡排序是如何实现的?

    无论学习哪一种编程语言,进行算法方面的训练时都绕不开“排序”。排序在进阶编程中有非常广泛的应用,要想成为编程高手,排序算法是必须要掌握的。而冒泡排序
    的头像 发表于 01-20 10:39 650次阅读
    php版冒泡<b class='flag-5'>排序</b>是如何实现的?

    jwt冒泡排序的原理

    jwt简介 冒泡排序: (Bubble Sort)是一种简单的交换排序。之所以叫做冒泡排序,因为我们可以把每个元素当成一个小气泡,根据气泡大小,一步一步移动到队伍的一端,最后形成一定对
    的头像 发表于 09-25 16:33 310次阅读
    jwt冒泡<b class='flag-5'>排序</b>的原理