生活消费
【深度剖析】 快速排序为什么不稳定?!
2025-01-03 06:35




最近做面试题中,遇到一些平时学习中比较少注意到的问题,记录下来以便后来者学习讨论。




要了解快速排序为什么不稳定,还需要从它的步骤原理入手。
那么,快速排序的步骤是什么呢

1、选取基准数字。
2、开始遍历,如果数字比基准大,则位置不变,如果比基准小,则将该值与前面第一个比基准大的值交换位置,如果前面没有比基准大的数字就不用替换了。
3、完成一边遍历后,交换头部的基准数字和最后一个比基准数字小的数字的位置,可以保证基准数字前面的值都小,后面的都大。
4、重复1-3的步骤。

快速排序 动图如下





既然要讨论快速排序为什么不稳定,那么也应该明确什么是稳定性

通常,在排序算法中 是指如果两个元素在原始数组中的相对顺序保持不变,则在排序后它们的相对顺序也应该保持不变。
换句话说,如果有两个相等的元素,它们的位置在排序之前是 a 和 b,且 a 在 b 的前面,那么在排序后,a 仍然应该在 b 的前面。





1、选取基准数字上,一般选取 头部(或尾部,此时,如果 相等元素 可能被分到 不同子数组,从而 改变 它们的 相对顺序

举个例子

数组为 [5, 3, 2, 5, 1],在基准数字选择为 元素 时,第一次分割后,数组变为 [3, 2, 1, 5, 5],其中左边的子数组 [3, 2, 1] 中的元素都小于基准 5,右边的子数组 [5, 5] 中的元素都 不小于 基准 5。然后,递归地对左右两部分进行排序,最后得到排序后的数组 [1, 2, 3, 5, 5]。
.
例子中,结果是正确的,但是可以看到,原数组中的两个相等的元素 5 的相对位置在排序后发生了变化。原本,第一个出现的 5 在第二个出现的 5 的前面,但在排序后,第一个出现的 5 在第二个出现的 5 的后面。而相等元素的相对顺序应该保持不变,显然这就 违背定义



2、既然选择头部和尾部都不稳定,那如果选取基准数字是 ,或者数组随机化,会不会也导致出现排序的不稳定? 答案是肯定的。

        假设基准数字是随机选择,此时它们的相对顺序是无法确定的。
        在快速排序每一次迭代中,基准数字将数组分割为两个子数组,其中一个子数组中的元素都小于基准,另一个子数组中的元素都大于基准。如果有相等的元素,那么它们可能会被随机选择的基准分配到不同的子数组中。
        这样,在每一次迭代中,相等元素的相对顺序可能会发生变化,因为它们被随机分配到不同的子数组。
        这样看来,基准数字的 似乎是稳定的。
        然而,由于基准数字是随机选择的,每次排序的结果可能都会不同。在某些情况下,随机选择的基准可能会导致相等元素的相对顺序发生变化,而在其他情况下,它们的相对顺序可能会保持不变。
        因此,快速排序在基准数字随机选择的情况下,虽然能够提高平均性能可能是稳定的,但也可能是不稳定的。



3、若是使用 ,一旦中间元被交换,与中间元相同的值与中间元的相对位置可能会被改变,除非新开O(n)空间。
而如果是 则该算法稳定,不过数组的插入本身效率低。





从前面的分析,我们不难找到,快速排序之所以不稳定是因为,相等元素的相对顺序发生变化。
要使得快速排序变得稳定,变要从此处切入。

那么便有以下思路

  • (1) 保留相等元素的相对顺序 :
           在进行元素比较和交换时,只有在相邻元素的值不相等时才进行交换。这样可以确保相等元素的相对顺序保持不变。但这个方法可能会导致排序的性能降低,因为需要额外的比较操作。
  • (2) 使用稳定的排序算法进行子数组的排序
           在快速排序的过程中,当遇到子数组的大小较小时,可以切换到使用稳定的排序算法,如归并排序或插入排序,对该子数组进行排序。这样可以保证子数组的稳定性,并最终保持整个排序的稳定性。

A 思路简述

基于快速排序的分治思想。选择数组中的一个元素作为枢轴(一般是第一个元素,然后将数组划分为两个子数组,其中一个子数组的元素都小于等于枢轴元素,另一个子数组的元素都大于枢轴元素。然后对这两个子数组分别递归调用快速排序算法,继续进行划分和排序。递归的基本情况是子数组的长度为1或0,即已经有序或为空数组,不需要再进行排序。通过不断划分和排序,最终实现整体的排序。在划分过程中,通过比较元素与枢轴的大小关系,将元素放置到正确的位置上,并维护相等元素的相对顺序。通过递归和划分的方式,快速排序算法能够高效地对一个数组进行排序


B 参考代码 :

 

C 算法分析


  • (1) 划分过程
    划分过程使用了双指针法,通过比较元素与枢轴的大小关系,将元素分为两个子数组。在相等元素时,使用交换操作保持相等元素的相对顺序。
  • (2) 递归过程:
    使用递归来对划分得到的子数组进行快速排序,分别递归调用quickSort函数。对于左子数组,递归调用quick_Sort_01(a, l, p-1),对于右子数组,递归调用quick_Sort_01(a, p+1, r)。
  • (3) 返回结果
    该算法是对原始数组进行原地排序,只是对原数组进行交换操作实现的排序,不需要返回额外的结果。





A 思路简述

        选择一个枢轴元素,将原始数组划分为两个子数组,其中一个子数组的元素都小于枢轴元素,另一个子数组的元素都大于等于枢轴元素。然后对两个子数组分别递归调用该算法进行排序,最后合并两个排序好的子数组,得到最终的排序结果。这个过程不断递归,直到子数组的长度为1或0,即达到了基本情况。通过分治和递归的思想,这个算法能够将一个大问题拆解为多个小问题,最终实现整体的排序。


B 参考代码

 
  • (1) 如果数组大小为1或更小,则已经排序完成
  • (2) 根据第一个元素(枢轴)对数组进行划分
  • (3) 将小于枢轴的元素放入左侧向量
  • (4) 将不小于枢轴的元素放入右侧向量
  • (5) 递归地对左右向量进行排序
  • (6) 将枢轴元素追加到左向量末尾
  • (7) 将排序后的右向量追加到左向量后面
  • (8) 返回合并后的排序向量

C 算法分析

  1. 枢轴选择
            传统的快速排序算法通常选择第一个或最后一个元素作为枢轴,并根据枢轴将数组划分为两个子数组。而这个方法将第一个元素作为枢轴,然后遍历剩余元素,将小于枢轴的元素放入左侧向量,大于枢轴的元素放入右侧向量。因此,枢轴元素不会在位置交换时移动。

  2. 循环方式
            传统的快速排序算法使用递归来划分和排序子数组。这个方法使用循环来遍历数组元素,并根据枢轴将它们划分为左右两个子数组,分别递归调用quick_Sort_02函数。对于左子数组,递归调用quick_Sort_02(l),对于右子数组,递归调用quick_Sort_02®。

  3. 子问题处理
            在递归调用时,这个方法使用类似快速排序的思想对左右子数组进行排序。然而,不同于原地排序的传统快速排序算法,这个方法每次递归都创建一个新的排序向量。

  4. 过递归调用MySort函数对子数组进行排序,并将排序好的左右子数组进行合并后返回最终的排序结果。




 
  • (1) 采用归并排序,merge()函数 用于将两个有序子数组 为一个有序数组。它接收一个数组 arr,以及左边界 l,中间位置 mid 和右边界 r,将位于左边界到中间位置的子数组和中间位置到右边界的子数组进行合并。
  • (2) 将元素拷贝到临时数组 left 中去。
  • (3) 将元素拷贝到临时数组 right 中去。
  • (4) 合并临时数组的元素到原数组
  • (5) 将剩余元素拷贝到数组
  • (6) mergeSort() 函数使用归并排序进行子数组排序,用于递归地将数组划分为子数组,然后调用 merge 函数进行合并。它接收一个数组 arr,以及左边界 low 和右边界 high,在数组范围内进行递归划分和排序。
  • (7) 递归排序左侧子数组
  • (8) 递归排序左侧子数组
  • (9) 合并两个有序子数组
  • (10) 判断待排序子数组的长度是否小于阈值 threshold,如果小于阈值,则调用稳定的归并排序算法 mergeSort 对该子数组进行排序。这样可以保证在处理较小范围的子数组时,算法仍能达到较高的效率,并且保持排序的稳定性。
    如果大于等于阈值,则继续进行快速排序的操作。
  • (11) 递归排序左侧子数组
  • (12) 递归排序右侧子数组

C 算法分析


结合了快速排序和归并排序的思想。

快速排序部分

选择一个枢轴元素,将数组划分为两个子数组,其中一个子数组的元素都小于等于枢轴元素,另一个子数组的元素都大于枢轴元素。
-对这两个子数组分别递归调用快速排序,继续进行划分和排序。
归并排序部分

将数组不断划分为更小的子数组,直到每个子数组只包含一个元素。
然后逐步合并相邻的子数组,保证合并后的数组仍然有序。
具体过程如下

在快速排序的递归过程中,检查子数组的长度是否小于阈值(threshold)。
如果小于阈值,就使用稳定的排序算法(这里使用归并排序)对子数组进行排序。
如果大于等于阈值,就继续使用快速排序算法进行划分和排序。
归并排序通过merge函数将有序的子数组合并,确保整体数组有序。



        这两种方法的实现可能需要对快速排序算法进行修改,增加一些额外的判断和操作。需要注意的是,这些修改可能会增加算法的复杂性和额外的性能开销。因此,通常情况下,快速排序被选择的主要原因是其在平均情况下具有较好的性能,而不是为了实现排序的稳定性。

    以上就是本篇文章【【深度剖析】 快速排序为什么不稳定?!】的全部内容了,欢迎阅览 ! 文章地址:http://ww.kub2b.com/news/19674.html
     栏目首页      相关文章      动态      同类文章      热门文章      网站地图      返回首页 企库往资讯移动站 http://ww.kub2b.com/mobile/ , 查看更多   
最新文章
京东万商 v6.2.2手机京东app下载「京东万商 v6.2.2」
uses-permission:'android.permission.INTERNET',允许程序访问网络连接,可能产生GPRS流量uses-permission:'android.permission.
三星Galaxy S8多少钱?三星Galaxy S8价格s8手机「三星Galaxy S8多少钱?三星Galaxy S8价格」
三星Galaxy S8多少钱  三星Galaxy S8的价格预计约6000元。   三星Galaxy S8基于Android7.0深度定制的UI,在主界面通过上下滑
如何设置路虎屏幕投屏?路虎手机「如何设置路虎屏幕投屏?」
要将手机屏幕内容投射到路虎车内的中控屏,有两种主要的方法,一种适用于安卓设备,一种适用于iPhone设备。首先,对于安卓设备,
林峯老婆张馨月再惹争议!用60元山寨手机壳被扒,删帖逃避引群嘲
娱乐圈从来不缺热闹,尤其是那些站在镁光灯边缘的“家属们”。最近,林峯的老婆张馨月(Carina)可谓是“热搜钉子户”,从检查离
百万新娘之爱无悔宝莲乘敏君沏茶的时候用她的手机给天祥发短信手机短信发不出去是什么原因「百万新娘之爱无悔宝莲乘敏君沏茶的时候用她的手机给天祥发短信」
很高兴和大家见面啦,我是小轮娱乐君,请多多指教。宝莲称敏君沏茶的时候,赶紧用她的手机给天祥发了短信,之后又装作有急事的样
小米手机怎么检测硬件,小米手机硬件检测教程
买了小米手机后,很多人会关心配置是否优越或存在不足。接下来,我将分享如何检测小米手机硬件的教程,帮助你了解设备性能与状况
京基智农2024年净利下滑59%
新京报讯(记者王思炀)4月1日,新京报记者了解到,日前召开2024年业绩说明会。2024年,京基智农实现营业收入59.60亿元,同比下
DNF:至尊天空价格&外观汇总!蝴蝶套最贵,墨染丹清最值得拿下
我们都知道自从DNF推出12套普通天空后,就不再推出了!虽说普通天空不再推出,但是至尊天空却一直在推出着。从第一套至尊天空若
两个android手机通过蓝牙连接手机蓝牙连接「两个android手机通过蓝牙连接」
在现代社会中,蓝牙已经成为了一种常见的无线通信技术。通过蓝牙,我们可以实现多种设备之间的连接和数据传输,比如手机与耳机、
炉石盒子工具版炉石传说盒子手机版「炉石盒子工具版」
炉石盒子工具版是一款非常好用的游戏辅助类应用,提供了很多的游戏资讯让用户可以第一时间掌握,而且还提供了最新的新手教学视频