快排与堆排的比较(std::sort实现分析)

今天面试被问到了快排与堆排的应用场景,思考了一下只答上来了数据基本有序的情况下堆排优于快排以及topK问题选择堆排,更进一步却答不上来。

后来发现其实堆排序和快速排序平均复杂度虽然都是O(NlogN)但是在最差情况下堆排复杂度也是O(NlogN)这一点比快排要好。但是稍微实验一下就能发现,堆排序虽然平均复杂度和快排是一样的,但是它平均交换元素次数是要比快排高出很多的,所以虽然时间开销都是NlogN但是堆排序的常数要大出不少,所以在元素基本无续的情况下快排速度还是会快一些。

还有就是在数据量逐渐增大的情况下,堆排序的交换元素次数随着数据量的增大而增大,所以性能开销也会越来越大,跟快速排序的差距就慢慢拉开了。所以在数据量较大的情况下选择快速排序是一个比较正确的选择。

这里不得不提一下stl算法中的std::sort这个排序函数了。这个标准库的排序算法还是十分高效的,底层实现是插入排序 + 快排 + 堆排。

首先讲一下为什么插入排序平均时间复杂度为O(N^2)的排序算法也能上榜吧。

插入排序:

插入排序虽然平均时间复杂度不是很乐观,但是在元素基本有序的情况下它的时间复杂度是接近O(N)的

快速排序:

我们都知道快速排序是基于分治的思想,需要通过递归来实现。当分段很小的情况下,快速排序还需要进行递归来交换数据,而递归需要将函数压栈,出栈,这一系列额外的负荷。所以在这种情况下快排的缺点就会被放大。

std::sort集合了三种算法的优点:

  • 在数据量很大的时候采用快排,此时时间复杂度是O(NlogN)。
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值