STL中的sort函数

STL sort算法解析

B站二面时,面试官问了一个问题,没打出来感觉挺亏的。

问题是:STL中的sort函数用的什么排序算法?这个问题我之前看面经的时候,看了一眼,但是当时没有仔细研究过。大致知道里面用了快速排序。

今天这里写一个文章总结下:

STL的sort()算法,数据量大时采用Quick Sort,分段递归排序。一旦分段后的数据量小于某个阈值,为避免Quick Sort的递归调用带来过大的额外开销,就改用Insertion Sort(插入排序)。如果递归层次过深,还会改用Heap Sort。


STL中的sort并非只是普通的快速排序,除了对普通的快速排序进行优化,它还结合了插入排序堆排序。根据不同的数量级别以及不同情况,能自动选用合适的排序方法。当数据量较大时采用快速排序,分段递归。一旦分段后的数据量小于某个阀值,为避免递归调用带来过大的额外负荷,便会改用插入排序。而如果递归层次过深,有出现最坏情况的倾向,还会改用堆排序。


快速排序最关键的地方在于枢轴的选择,最坏的情况发生在分割时产生了一个空的区间,这样就完全没有达到分割的效果。STL采用的做法称为median-of-three,即取整个序列的首、尾、中央三个地方的元素,以其中值作为枢轴。



### C++ STL 中 `sort` 函数的实现 在 C++ 的标准模板库 (STL) 中,`std::sort` 是一种高效的排序算法,通常基于快速排序(Quick Sort),但在某些情况下会切换到堆排序(Heap Sort)或插入排序(Insertion Sort)。这种混合排序方法被称为 **Introsort**[^1]。 #### Introsort 工作原理 - 开始时采用快速排序来处理大部分数据集。 - 当递归深度超过一定阈值时,转而使用堆排序以防止最坏情况的发生。 - 对于非常小的数据子集,则应用插入排序提高效率。 这种方法结合了不同排序算法的优点,在平均性能和最差性能之间取得了良好的平衡。以下是简化版的伪代码表示: ```cpp template<typename RandomIt> void introsort_util(RandomIt first, RandomIt last, int depth_limit) { while ((last - first) > size_threshold) { // 如果剩余元素多于阈值 if (depth_limit == 0) { // 达到了最大递归深度 make_heap(first, last); sort_heap(first, last); // 转换成堆并排序 return; } --depth_limit; RandomIt cut = partition(first, last); // 执行一次划分操作 introsort_util(cut, last, depth_limit); // 递归处理右半部分 last = cut; // 更新边界继续左半部分 } insertion_sort(first, last); // 小规模数据直接用插入排序 } ``` 对于实际使用的场景来说,可以直接通过如下方式调用 `std::sort` 来对容器中的元素进行排序: ```cpp #include <algorithm> // 包含 std::sort 定义 #include <vector> int main() { std::vector<int> v = {5, 2, 9, 1, 5, 6}; std::sort(v.begin(), v.end()); // 对整个 vector 进行升序排列 for(auto& elem : v){ printf("%d ", elem); } } ``` 此段代码展示了如何利用 `<algorithm>` 库中的 `std::sort` 方法完成基本类型的排序工作[^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值