写在前面

Q:什么容器适合sort()算法?
A:vector, deque

  • 关系型容器的底层采用红黑树,具有自动排序的功能,不需用sort()算法
  • 序列式容器中的stack,queue,priority_queue都有特别的出入口,不允许对元素进行排序;list的迭代器属于BidirectionIterator(双向迭代器),而sort算法的迭代器属于RandomAccessIterator(随机存取迭代器),list自己定义了相应的成员函数来实现排序

sort()算法

参考链接:https://zhuanlan.zhihu.com/p/36274119

STL的sort()算法涉及到了三种排序算法:快排、直接插入、堆排
STL中的sort()算法原理

快排的时间复杂度为O(nlogn),但是在最坏的情况下(在分隔时出现子区间为空的情况),快排的时间复杂度达到O(n^2),此时递归的层数也会越来越深。在数据量小的情况下,数据基本有序时,采用直接插入排序比快排更快。

堆排的时间复杂度恒为O(nlogn),无论数据有什么特征它的时间复杂度是不变的,虽然时间复杂度和快排相同,当时总体来说没有快排的速度快,主要原因在于,堆排涉及到大量的交换操作。

为了避免快排恶化到O(n^2)的时间复杂度,当递归的层数达到一定值时,转而采用堆排序。
当数据量小于某个值(SGI STL中设定的是16)时,采用直接插入排序

代码实现:

  • 快排的基准值采用:三点中值,也就是序列的首元素、尾元素以及中间元素这三者的中值

1.sort函数
STL中的sort()算法原理
__lg函数:计算对数

STL中的sort()算法原理


2.__introsort_loop涉及到快排和堆排
当递归深度大于depth_limit时,采用堆排partial_sort
STL中的sort()算法原理
快排分隔函数__unguarded_partition
STL中的sort()算法原理
快排基准值选取函数__median
STL中的sort()算法原理


3.__final_insertion_sort涉及到插入排序
当序列长度不大于16时采用插入排序
STL中的sort()算法原理
如果长度不大于16,直接调用插入排序的函数__insertion_sort,否则将前16个元素进行插入排序,后面的元素通过循环调用插入排序的内层循环处理函数__unguarded_linear_insert()处理
STL中的sort()算法原理


补充:插入排序
STL中的sort()算法原理
STL中的sort()算法原理
STL中的sort()算法原理

总结

sort()算法的过程:

  • 算法中涉及到两个阈值,子序列的长度(程序中设定为16),递归的深度(2logn)
  • 首先如果序列的长度大于16调用快排函数进行处理,否则直接进行插入排序
  • 快排处理的过程中需要判断递归的深度,当递归的深度超过阈值时,采用堆排进行处理
  • 快排过程结束后,此时元素已基本有序,采用直接插入进行处理

相关文章:

  • 2022-12-23
  • 2021-12-20
  • 2021-10-31
  • 2019-09-28
  • 2021-06-03
  • 2021-11-19
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-01-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-01-07
  • 2022-02-03
相关资源
相似解决方案