在std :: sort()中使用哪种类型的排序?

时间:2009-12-03 14:17:20

标签: c++ sorting stl

任何人都可以告诉我在std::sort()头文件中定义的<algorithm>函数中实现了哪种类型的排序技术(冒泡,插入,选择,快速,合并,计数......) ?

7 个答案:

答案 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的源代码。

  

最有可能使用QuickSortQuickSort 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 filestd::__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。