排序是实际生产和算法竞赛中都经常会用到的东西,也是理论计算机研究相对比较多的领域。基于比较的排序的理论下界非常容易获得,然而还是没有算法能够确切地达到这个下界,目前最好的逼近是 Merge-Insertion ,可以在规模比较小的时候严格取到下界。https://en.wikipedia.org/wiki/Merge-insertion_sort
C++ 以速度快著称,那么标准库里实现的排序使用的是什么算法呢?
根据 cppref ,我们找到 libstdc++ 的实现代码:
template<typename _RandomAccessIterator, typename _Size, typename _Compare>void__introsort_loop(_RandomAccessIterator __first,_RandomAccessIterator __last,_Size __depth_limit, _Compare __comp){while (__last - __first > int(_S_threshold)){if (__depth_limit == 0){std::__partial_sort(__first, __last, __last, __comp);return;}--__depth_limit;_RandomAccessIterator __cut =std::__unguarded_partition_pivot(__first, __last, __comp);std::__introsort_loop(__cut, __last, __depth_limit, __comp);__last = __cut;}}// sorttemplate<typename _RandomAccessIterator, typename _Compare>inline void__sort(_RandomAccessIterator __first, _RandomAccessIterator __last,_Compare __comp){if (__first != __last){std::__introsort_loop(__first, __last,std::__lg(__last - __first) * 2,__comp);std::__final_insertion_sort(__first, __last, __comp);}}
这里截取了一个片段,我们可以看到它的算法实际上是 intro sort 算法。这是一种融合算法,在数据规模大于 3 的时候我们使用快排,同时记录一个深度的余额(一开始的时候设为)。每次递归的时候深度的余额就会自减,如果余额不足就会转而使用堆排,防止遇到非常极端的数据快排会被卡到
。如果递归到了数据规模小于等于 3 的时候就会使用插入排序。
