C++ STL sort函数的底层实现

本文探讨了sort函数中的内省式排序策略,通过快速排序与堆排序的优化组合,针对不同规模数组选择高效算法。当子数组短时,插入排序在近乎有序数组中表现出色。理解这些排序算法如何在实际场景中平衡效率与复杂度。
摘要由CSDN通过智能技术生成

sort函数的底层用到的是内省式排序以及插入排序,内省排序首先从快速排序开始,当递归深度超过一定深度(深度为排序元素数量的对数值)后转为堆排序。

先来回顾一下以上提到的3中排序方法:

  • 快速排序:先选一个基准值(一般为首值),将比它大的数置于其右侧,将比它小的数置于它左侧,那么这个基准值所在的位置定是整个数组的有序位。然后递归该基准左右两子数组。算法复杂度为nlogn;
  • 堆排序:将数组建立成大顶堆,重复从堆顶取出数值最大的结点(把根结点和最后一个结点交换,把交换后的最后一个结点移出堆,移出的这个数值为未排序数组的最后),并让残余的堆维持大顶堆的性质。时间复杂度为nlogn;
  • 插入排序:对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。时间复杂度为n2;

其中先讲下快排和堆排,快排的平均复杂度为nlogn,但是它的复杂度是根据基准值来决定的,基准值选择的不好,最坏的复杂度会达到n2,而堆排序的复杂度是一定的为n*logn,那为什么不直接使用堆排序呢,是因为在将堆顶值与最后一个结点值交换并移除最后一个值后,在重新建堆的过程中,交换到堆顶的值显然比每个结点要小,但还是要经过对比判断,这个判断其实是多余的,因此这是它相比快排较慢的原因。

于是,内省式排序结合了快排和堆排的特点,当快速排序到大一定深度(2logn)时,采用堆排序,以维持n*logn的复杂度。

在sort函数中,内省排序过程中子数组长度小于16时,采用的是插入排序,因为当数组长度较短时,就是数组已经大致排序过了,对大致有序的数组(即逆序对不多了)用插入排序的算法复杂度会很小,可以想象成理牌的过程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值