任何人都可以告诉我在std::sort()
头文件中定义的<algorithm>
函数中实现了哪种类型的排序技术(冒泡,插入,选择,快速,合并,计数......) ?
答案 0 :(得分:28)
std::sort
的大多数实现都使用quicksort,(或者通常是一种混合算法,如introsort,它结合了quicksort,heapsort和插入排序)。
标准要求的唯一要求是std::sort
按照指定的顺序以某种方式对数据进行排序,其复杂度约为O(N log(N));它不能保证稳定。从技术上讲,introsort比quicksort更能满足复杂性要求,因为quicksort具有二次最坏情况时间。
答案 1 :(得分:10)
C ++标准ISO / IEC 14882:2003
25.3.1.1排序
template<class RandomAccessIterator> void sort(RandomAccessIterator first, RandomAccessIterator last); template<class RandomAccessIterator, class Compare> void sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
1 效果:对元素进行排序 范围[第一,最后)。
2 复杂性: 大约N log N(其中N == last - 首先)平均比较。
没有关于方法的信息,但复杂性总是N log N
。
答案 2 :(得分:7)
MSVC2013 STL中使用了三种算法,参考std::sort
的源代码。
最有可能使用
QuickSort
或QuickSort
IntroSort
之间的变体。如果递归过深,将在此处使用
HeapSort
。否则将使用
InsertSort
。
答案 3 :(得分:4)
可能std::sort
的所有实现都使用 introsort (又名内省排序),这是一种结合了quicksort和heapsort的混合算法。实际上, introsort 是在1997年特别发明的,目的是在C ++ STL中进行高性能的实现。
标准要求的唯一内容是std::sort
按照指定的排序以某种方式对数据进行排序,复杂度为 O(N log(N));它不能保证稳定(如果需要,可以使用单独的std::stable_sort
算法。)
从技术上讲,introsort比quicksort更能满足复杂性要求:这是因为在最坏的情况下,heapsort保证了 O(N log(N))的复杂性,而quicksort具有二次最坏情况时间。
然而,heapsort更慢&#39;比起平均情况下的快速排序,在某种意义上,heapsort执行 C * N log(N)而快速排序具有 D * N log(n)性能,其中 D 明显小于 C (数字 C 和 D 是常量)。换句话说,heapsort的每个比较开销高于快速排序。
为了充分利用这两个方面,introsort以quicksort -a递归算法开始,但是当递归深度过高时(这意味着它会进入退化的最坏情况行为),它切换到heapsort。
另请参阅David the Wikipedia entry for introsort或David Musser的original paper,他发明了特别针对STL的内容。
答案 4 :(得分:1)
GCC 9.2.0 libstdc ++源确认为内向排序
其他have mentioned introsort,但这是libstc ++的一些证据,它是大多数Linux发行版中的默认C ++实现。
libstdc ++是GCC本身的一部分,因此我们将研究GCC源代码。
libstdc++-v3/include/std/algorithm是主要标头,包含:
#include <bits/stl_algobase.h>
#include <bits/stl_algo.h>
然后,bits/stl_algo.h包含排序重载的定义,其中之一是:
/**
* @brief Sort the elements of a sequence.
* @ingroup sorting_algorithms
* @param __first An iterator.
* @param __last Another iterator.
* @return Nothing.
*
* Sorts the elements in the range @p [__first,__last) in ascending order,
* such that for each iterator @e i in the range @p [__first,__last-1),
* *(i+1)<*i is false.
*
* The relative ordering of equivalent elements is not preserved, use
* @p stable_sort() if this is needed.
*/
template<typename _RandomAccessIterator>
inline void
sort(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_function_requires(_LessThanComparableConcept<
typename iterator_traits<_RandomAccessIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive(__first, __last);
std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
}
所以我们看到这只是对输入进行了一系列的完整性检查,然后调用了defined in the same file的std::__sort
:
template<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);
}
}
我将在这里停止,我们到达了一个名为std::__introsort_loop
的标识符,其余的实现都在同一个文件上,如果有人仍有疑问。
GDB也应可以逐步调试到std::sort
中而无需在Ubuntu 18.04中进行任何进一步的设置,如What is the underlying data structure of a STL set in C++?中对std::set
所述:
C ++ 17并行排序
我们现在也有并行排序,因此值得一看的是如何进行:Are C++17 Parallel Algorithms implemented already?
如上面的答案中所述,该实现依赖于一个外部库:Intel Thread Building Blocks:https://github.com/intel/tbb
答案 5 :(得分:0)
你的意思是std :: sort?如果是这样,它可以以他们想要的任何方式实现。它可能是快速排序,但可能是基数或其他东西。只要它产生一个至少为O(n log n)的排序列表,实现就可以了,afaik。
答案 6 :(得分:0)
只是一些实证结果:
我使用stump :: sort(VS2008工具链)将使用numpy 1.9.2 sort的python脚本翻译成C ++。
当我使用numpy.sort参数kind =&#39; mergesort&#39;时,我只能在python和C ++方面获得相同的结果。当kind =&#39; quicksort&#39;对于具有相同键的元素,我得到不同的相对排序。或亲切=&#39; heapsort&#39;。所以我想至少对于VS2008 std :: sort附带的STL版本使用mergesort。