快速排序的稳定性分析

    快速排序是一个不稳定的排序算法,本文将着重分析该算法不稳定的原因所在。

    首先,考虑下图中对一个关键字都为 1 的序列所进行的交换操作。

     

     

      如图,交换前,枢纽元已放置在最后一个位置。图中,当遇到和枢纽元大小相同的元素时,游标 i 选择继续前进直到与游标 j 相遇为止,然后将枢纽元与游标  i  和 j 所指向的元素交换, 再递归的对左右两边的数组进行快速排序,这是快速排序的思想。

     但问题也出现了。如图,一轮递归结束后,左右两边的数组明显失衡,可想而知,左边数组仅仅是一个长度与当前数组相当的子数组,右边的数组长度为1,递归算法的复杂度将上升为 \small O\left ( N^2 \right ) ,这触犯了快速排序的 “大忌” !

     程序恶化的原因: 当游标所指向的元素同枢纽元相等时选择了继续前进,而不是停留在原地,这就导致游标肆无忌惮的一路向前,根本没有顾及到左右两个数组是否均衡,因而触犯了“大忌”。

     避免踩坑: 当游标所指向的元素同枢纽元相等时,待在原地不动,左右游标指向的元素进行交换,再各自向前移动。

     下图是没有踩坑的操作示意。

      

     

     据图,我们似乎做了很多没有必要的交换。但这样做使得最终的枢纽元出现在数组的中间位置上,左右数组呈均衡状态,理论上时间复杂度将是 \small O\left ( Nlog\left ( N \right ) \right ),快速排序的性能是最优的,避免了我们陷入复杂度为 \small O\left ( N^2 \right ) 的坑。

     本文的例子在实际当中很少出现,但当一个序列中存在大量重复的元素,此时如果选择游标继续前进的策略,无疑也会陷入性能上的低谷。

 

    结论: 根据上面的讨论,快速排序出于性能上的考虑,牺牲了算法的稳定性。虽然可以改变交换规则,使得算法保持稳定性,但却牺牲了性能,对于一个排序算法而言,这是得不偿失的,除非是上下文有稳定性方面的需求,否则,不建议改变交换规则。

  • 23
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值