std::sort() 中使用哪种类型的排序?
谁能告诉我在 std::sort()
函数中实现了哪种类型的排序技术(冒泡、插入、选择、快速、合并、计数...) ><算法>头文件?
Can anyone please tell me that which type of sorting technique (bubble, insertion, selection, quick, merge, count...) is implemented in the std::sort()
function defined in the <algorithm>
header file?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
std::sort 的大多数实现都使用快速排序(或者通常是像 introsort 这样的混合算法,它结合了快速排序、堆排序和插入排序)。
标准唯一要求的是 std::sort 以某种方式根据指定的顺序对数据进行排序,复杂度约为 O(N log(N));不保证稳定。从技术上讲,内推排序比快速排序更好地满足复杂性要求,因为快速排序的最坏情况时间是二次的。
Most implementations of
std::sort
use quicksort, (or usually a hybrid algorithm like introsort, which combines quicksort, heapsort and insertion sort).The only thing the standard requires is that
std::sort
somehow sort the data according to the specified ordering with a complexity of approximately O(N log(N)); it is not guaranteed to be stable. Technically, introsort better meets the complexity requirement than quicksort, because quicksort has quadratic worst-case time.C++ 标准 ISO/IEC 14882:2003
没有有关方法的信息,但复杂性始终为
N log N
。C++ Standard ISO/IEC 14882:2003
There is no information about method but complexity is always
N log N
.MSVC2013 STL中使用了三种算法,参考
std::sort
源码。There are three algorithms that are used in MSVC2013 STL, referring to the source code of
std::sort
.可能
std::sort
的所有实现都使用 introsort(又名内省排序),这是一种结合了快速排序和堆排序的混合算法。实际上,introsort 是在 1997 年专门发明的,目的是在 C++ STL 中实现高性能排序。标准唯一要求的是 std::sort 以某种方式根据指定的顺序对数据进行排序,复杂度为 O(N log(N));它不保证稳定(如果需要的话,可以使用单独的 std::stable_sort 算法)。
从技术上讲,introsort 比快速排序更能满足复杂性要求:这是因为堆排序在最坏情况下保证了 O(N log(N)) 复杂性,而快速排序在最坏情况下的时间是二次方。
然而,在一般情况下,堆排序比快速排序“慢”,因为堆排序执行C*N log(N),而快速排序执行D*N log(n) > 性能,D 明显小于 C(数字 C 和 D 是常数)。换句话说,堆排序的每次比较开销高于快速排序。
为了获得两全其美的效果,introsort 从快速排序(一种递归算法)开始,但是当递归深度变得太高时(这意味着它会陷入退化最坏情况的行为),它会切换到堆排序。
另请参阅introsort 的 Wikipedia 条目 或 来自 David Musser 的原始论文,他专门为 STL 发明了 introsort。
Probably all implementations of
std::sort
use introsort (aka introspection sort), a hybrid algorithm that combines quicksort and heapsort. Actually, introsort was particularly invented in 1997 for the purpose of a performant sort implemenation in C++ STL.The only thing the standard requires is that
std::sort
somehow sort the data according to the specified ordering with a complexity of O(N log(N)); it is not guaranteed to be stable (there is a separatestd::stable_sort
algorithms available, if this should be required).Technically, introsort better meets the complexity requirement than quicksort: This is because heapsort has guaranteed O(N log(N)) complexity in the worst case, whereas quicksort has quadratic worst-case time.
However, heapsort is 'slower' than quicksort in the average case, in the sense that heapsort performs C*N log(N) whereas quicksort has D*N log(n) performance, with D being significantly smaller than C (the numbers C and D are constants). In other words, the per-comparison-overhead of heapsort is higher than the one of quicksort.
To get the best of both worlds, introsort starts with quicksort —a recursive algorithm—, but when recursion depth gets too high (which means it gets into a degenerated worst-case behaviour), it switches to heapsort.
See also the Wikipedia entry for introsort or the original paper from David Musser, who invented introsort particularly for STL.
GCC 9.2.0 libstdc++ 源确认 introsort
其他提到了 introsort,但这里有一些证据libstc++,这是大多数 Linux 发行版上的默认 C++ 实现。
libstdc++ 是 GCC 本身的一部分,因此我们将研究 GCC 源代码。
libstdc++- v3/include/std/algorithm 是主标头,包含:
然后, bits/stl_algo.h 包含排序重载的定义,其中之一是:
所以我们看到这只是对输入进行一系列健全性检查,然后调用
std::__sort
,即 在同一个文件中定义:我们已经到达了一个标识符称为 std::__introsort_loop ,其余的实现位于同一个文件上,任何人仍然有疑问。
在 Ubuntu 18.04 中,也应该可以将 GDB 单步调试到
std::sort
中,而无需进行任何进一步的设置,如std::set
中所述:STL集的底层数据结构是什么在 C++ 中?C++17 并行排序
我们现在也有并行排序,因此也值得研究一下它是如何完成的:C++17 并行算法已经实现了吗?
正如上面的答案中提到的,实现依赖于外部库:英特尔线程构建模块:https://github.com/intel/tbb
GCC 9.2.0 libstdc++ source confirming introsort
Others have mentioned introsort, but here is some evidence for libstc++, which is the default C++ implementation on most Linux distros.
libstdc++ is a part of GCC itself, so we will look into GCC source.
libstdc++-v3/include/std/algorithm is the main header and contains:
Then, bits/stl_algo.h contains the definition of the sort overloads, one of them being:
so we see that this just does a bunch of sanity checks on the input, and then calls
std::__sort
which is defined in the same file:and I'll stop here that we have reached an identifier called
std::__introsort_loop
, the rest of the implementation is on the same file is anyone still has doubts.It should also be possible to GDB step debug into
std::sort
without any further setup in Ubuntu 18.04 as mentioned forstd::set
at: What is the underlying data structure of a STL set in C++?C++17 parallel sorting
We now also have parallel sorting, so it would be worth looking on how it is done as well: Are C++17 Parallel Algorithms implemented already?
As mentioned in the above answer, the implementation relies on an external library: Intel Thread Building Blocks: https://github.com/intel/tbb
您的意思是 std::sort 吗?如果是这样,就可以按照他们想要的任何方式实施。它可能是快速排序,但也可能是基数或其他东西。据我所知,只要它能在至少 O(n log n) 内生成一个排序列表,实现就可以了。
Do you mean std::sort? If so it can be implemented any way they want. Its probably Quick sort but could be radix or something else. As long as it produces you a sorted list in at least O(n log n) the implementation is fine, afaik.
只是一些经验结果:
我使用 std::sort (VS2008 工具链)将使用 numpy 1.9.2 sort 的 python 脚本翻译为 C++。
当我使用 numpy.sort 参数 kind='mergesort' 时,我只能在 python 和 C++ 方面得到相同的精确结果。当 kind='quicksort' 或 kind='heapsort' 时,具有相同键的元素的相对顺序不同。所以我猜想至少对于VS2008 std::sort自带的STL版本来说是使用mergesort的。
Just some empirical results:
I translated a python script using numpy 1.9.2 sort to C++ using std::sort (VS2008 toolchain).
I only get the same exact results in the python and C++ sides when I use numpy.sort argument kind='mergesort'. I get different relative ordering for elements with same key when kind='quicksort' or kind='heapsort'. So I guess that at least for the version of STL that comes with VS2008 std::sort uses mergesort.