关于C++标准库中的sort函数

参考资料,点击前往

C++里面的sort简单理解就是一个快排,但是要仔细分析,他其实集成了插入排序、堆排、快排三种排序各自的优点

  1. 在数据量很大的时候,使用快排
  2. 在递归过程中,分段之后的数据量小于某个值(或者原本数据量就很小)的时候,使用插入排序
  3. 在递归过程中,如果递归层次过深,分割行为有恶化倾向时,它能够自动侦测出来,使用堆排序来处理,在此情况下,使其效率维持在堆排序的O(N logN),但这又比一开始使用堆排序好

我简单猜一下这么设计的原因:

  1. 为什么要选用快排
  2. 为什么要引入插入
  3. 为什么要引入堆排

第一点:
虽然归并,快排,堆排的复杂度都是O(nlogn),但是通过大数据测试(不是我),快排的平均表现要比其他方法快
快排比堆排快的原因之一:相对而言,堆排过程中两者比较的次数要比快排多
快排比归并快的原因之一:相对而言,归并过程中内存写的操作要比快排多,
快排比归并快的原因之二:还有就是,底层而言,每句话都是需要时间去处理的,平时的话,时间很短,基本忽略影响,但是数量级大了,还是有一定影响的。简单来说,快排操作的次数要少一点

而且通过名字就知道他肯定很快,要不怎么叫快速排序

第二点:
sort简单理解为:当数据量少的时候用插入,多的时候用快排
这里就不说是优点还是缺点了,只说他们的一些特征。
插入: 平均时间复杂度O(n ^ 2),最好复杂度O(n),最坏复杂度O(n ^ 2)
什么时候最好呢?在数据有序的时候,这时候是极限O(n),当大致有序的时候,稍微有点出入,但是也不影响,约等于O(n)
快排: 平均时间复杂度O(nlogn),最好复杂度O(nlogn),最坏复杂度O(n ^ 2)
最好的时候,每次分割的两个部分都很平均,但是发现了没,最好的时候不如插入的O(n)
最坏的时候,每次只分割成一个元素和另一部分,这种情况就相当于冒泡
个人见解:其实快排中间值如何取是一件玄学的事情,不管怎么取都有一种特殊情况,在这种情况下,是O(n^2)的复杂度,之前我听过一个说法,当数据本身有序的时候,快排是最慢的,这个时候你想到了什么,是不是想到了插入在这个时候是最快的。
我觉得这也可能是引入插入的其中一个原因

第三点:
既然快排和插入已经可以解决问题了,为什么要引入堆排序,为什么不引入归并
其实上面已经有了答案:快排是通过递归实现的,而递归很浪费时间(具体可能是一些内存方面的知识,我猜的),如果递归很多层的话,还是很浪费时间的,这个时候就需要一个不是递归,但是同样很快的方法来替换快排,那就是堆排。堆排的是所有复杂度都是O(nlogn),他虽然建立了一个堆,有点递归的意思,但是他不可能出现恶化的倾向。
而且堆排一直是快排有力的竞争者。
那为什么不是归并呢,因为归并也是递归的呀

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值