c++之stl_sort

本文详细介绍了C++中的STL_sort算法,该算法基于快速排序,配合插入排序和堆排序,保持平均时间复杂度为O(nlogn)。在小规模或部分有序的数据上,插入排序效率更高,而当递归深度超过一定阈值时,会切换到堆排序以确保效率。文章提供了完整的代码实现,并提及了排序算法的选取策略。
摘要由CSDN通过智能技术生成

c++之stl_sort

1.前言

stl_sort,不搜不知道一搜吓一跳,它有一个专有名字,introspective sort。以快排为核心,配合插排、堆排,将时间复杂度维持在 O ( n l o g n ) O(nlogn) O(nlogn)

本文,基于C#的Array.Sort来实现,原理是类似的,在实现方面可能会有一些差别。
插排、堆排、快排的实现原理,请戳这里

2.实现

有了上述三种排序算法的基础,就容易许多了。

  1. 元素个数检查(threshold)。当序列剩余元素小于此值时,使用插排。在排序有序序列的时候,插排时间复杂度为 O ( n ) O(n) O(n)。当数据量小的时候,插排很快;当数据量大,且无序的时候,指数爆炸 O ( n 2 ) O(n^2) O(n2),效率极低(几个小时无法完成10000w随机数组?,闲得蛋疼)。
  2. 设置递归深度(depthLimit)。大家都知道,快排很快,但是时间复杂度不稳定,最快的情况 O ( n l o g n ) O(nlogn) O(nlogn),最慢的情况 O ( n 2 ) O(n^2) O(n2),这是由于递归恶化。选取一个好的pivot,对效率影响很大(pivot的选取问题已经在之前的博客里优化了)。但无论怎样设计,都不可能永远保证pivot的值接近序列的中值,所以机智的大佬们设计了一个阈值,当当递归深度大于这个阈值的时候,采用堆排。堆排虽然时间复杂度稳定在 O ( n l o g n ) O(nlogn) O(nlogn),但是多数情况下,它的效率并没有快排高,堆排的判断分支过多。也就是说,使用堆排是一种“补救措施”
  3. threshold的取值并没有什么数学公式可言,来自于经验;depthLimit的取值则有讲究,具体看源码吧。

3.完整代码

环境:mingw64

如何使用:

#include <iostream>
#include "m_sort.h"

int main(){
   
    int *a = new int[50];
    srand(1);
    for (size_t i = 0; i < 50; i++)
    {
   
        a[i] = rand();
        cout << a[i] << " ";
    }

    // InsertionSort(a, 0, 49, [](const int &a, const int &b) { return a - b; });
    // QSort(a, 0, 49, [](const int &a, const int &b) { return a - b; });
     <
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值