STL中sort 用的是快排吗? - 快排、堆排(heap sort)、插入排序

插入排序优势

插入排序复杂度虽然是O(n^2);
但是其时间复杂度中常数项小,并在优化情况下,小数据量时,有更快的优势;
其他复杂排序,有递归等操作带来的额外的负荷;
我这版STL中,判断用快排还是用插入排序的阈值选用的时32 ;
在这里插入图片描述

STL 对快排和插入排序的抉择

这里在for的时候,计算了数据量,根据数据量大于32、小于32 来判断:用快排 or 用插入排序;
每次递归进去,都需要判断,递归到一定的数据量还是改为插入;所以这样的sort 是快排中混着插入来做的;

template <class _RanIt, class _Pr>
_CONSTEXPR20 void _Sort_unchecked(_RanIt _First, _RanIt _Last,
					 _Iter_diff_t<_RanIt> _Ideal, _Pr _Pred) {
    // order [_First, _Last)
    for (;;) {
        if (_Last - _First <= _ISORT_MAX) { // small
            _Insertion_sort_unchecked(_First, _Last, _Pred);
            return;
        }

        if (_Ideal <= 0) { // heap sort if too many divisions
            _Make_heap_unchecked(_First, _Last, _Pred);
            _Sort_heap_unchecked(_First, _Last, _Pred);
            return;
        }

        // divide and conquer by quicksort
        auto _Mid = _Partition_by_median_guess_unchecked(_First, _Last, _Pred);

        _Ideal = (_Ideal >> 1) + (_Ideal >> 2); // allow 1.5 log2(N) divisions

        if (_Mid.first - _First < _Last - _Mid.second) { // loop on second half
            _Sort_unchecked(_First, _Mid.first, _Ideal, _Pred);
            _First = _Mid.second;
        } else { // loop on first half
            _Sort_unchecked(_Mid.second, _Last, _Ideal, _Pred);
            _Last = _Mid.first;
        }
    }
}

什么时间用堆排;

看源码时候发现:在一定情况下用到了堆排;好奇心驱使,看了一下;
其实就是每次递归计算递归深度,根据深度来决策继续快排还是堆排;
其实很正常,快排有可能退化,而堆排时间复杂度稳定,为了减少退化,肯定要优化;

这个_Ideal的初始值就是数据量长度;每递归一层,都会减少,减少到0就不再快排了;每次递归进行计算;到一定的递归深度;数据量还大于32,就改用堆排;其实就是为了避免递归深度太深;
在这里插入图片描述

总结

STL中,大数据排序时候,首选了快排;
递归深度到达一定程度的时候,选择了堆排;(允许1.5 log2(N) 的递归深度)
数据量小到一定程度的时候,选择插入排序;(小于32个数据时候)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
make_heap、push_heap、pop_heapsort_heap都是C++ STL算法,用于操作堆(heap)数据结构。 1. make_heap:将一个无序的区间转换为堆。函数原型如下: ``` template <class RandomAccessIterator> void make_heap (RandomAccessIterator first, RandomAccessIterator last); ``` 其,first和last分别为区间的起始和结束迭代器。make_heap函数会将[first,last)区间转换为堆。调用该函数后,该区间的最大元素会被放在第一个位置上。 2. push_heap:将一个元素添加到堆。函数原型如下: ``` template <class RandomAccessIterator> void push_heap (RandomAccessIterator first, RandomAccessIterator last); ``` 其,first和last分别为区间的起始和结束迭代器。当前,[first,last-1)已经是一个堆,push_heap函数将last-1位置的元素添加到堆,并且保证该堆仍然是一个堆。 3. pop_heap:将堆的最大元素移动到末尾。函数原型如下: ``` template <class RandomAccessIterator> void pop_heap (RandomAccessIterator first, RandomAccessIterator last); ``` 其,first和last分别为区间的起始和结束迭代器。当前,[first,last)已经是一个堆,pop_heap函数将该堆的最大元素(即first位置的元素)移动到last-1位置,并且保证[first,last-1)仍然是一个堆。 4. sort_heap:将一个堆排序。函数原型如下: ``` template <class RandomAccessIterator> void sort_heap (RandomAccessIterator first, RandomAccessIterator last); ``` 其,first和last分别为区间的起始和结束迭代器。当前,[first,last)已经是一个堆,sort_heap函数会将该堆转换为有序序列。 需要注意的是,这几个函数都要求操作的区间是一个随机访问迭代器(RandomAccessIterator)类型的迭代器。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值