STL sort
STL的sort()算法,数据量大时采用Quick Sort,分段递归排序,一旦分段后的数据量小于某个门槛,为避免Quick Sort的递归调用带来过大的额外负荷,就改用Insertion Sort。如果递归层次过深,还会改用Heap Sort。本文先分别介绍这个三个Sort,再整合分析STL sort算法(以上三种算法的综合) -- Introspective Sorting(内省式排序)。
一、Insertion Sort
- Insertion Sort
- // 默认以渐增方式排序
- template <class RandomAccessIterator>
- void __insertion_sort(RandomAccessIterator first,
- RandomAccessIterator last)
- {
- if (first == last) return;
- // --- insertion sort 外循环 ---
- for (RandomAccessIterator i = first + 1; i != last; ++i)
- __linear_insert(first, i, value_type(first));
- // 以上,[first,i) 形成一个子区间
- }
- template <class RandomAccessIterator, class T>
- inline void __linear_insert(RandomAccessIterator first,
- RandomAccessIterator last, T*)
- {
- T value = *last; // 记录尾元素
- if (value < *first){ // 尾比头还小 (注意,头端必为最小元素)
- copy_backward(first, last, last + 1); // 将整个区间向右移一个位置
- *first = value; // 令头元素等于原先的尾元素值
- }
- else // 尾不小于头
- __unguarded_linear_insert(last, value);
- }
- template <class RandomAccessIterator, class T>
- void __unguarded_linear_insert(RandomAccessIterator last, T value)
- {
- RandomAccessIterator next = last;
- --next;
- // --- insertion sort 内循环 ---
- // 注意,一旦不再出现逆转对(inversion),循环就可以结束了
- while (value < *next){ // 逆转对(inversion)存在
- *last = *next; // 调整
- last = next; // 调整迭代器
- --next; // 左移一个位置
- }
- *last = value; // value 的正确落脚处
- }
二、Quick Sort
- Quick Sort
- // 返回 a,b,c之居中者
- template <class T>
- inline const T& __median(const T& a, const T& b, const T& c)
- {
- if (a < b)
- if (b < c) // a < b < c
- return b;
- else if (a < c) // a < b, b >= c, a < c --> a < b <= c
- return c;
- else // a < b, b >= c, a >= c --> c <= a < b
- return a;
- else if (a < c) // c > a >= b
- return a;
- else if (b < c) // a >= b, a >= c, b < c --> b < c <= a
- return c;
- else // a >= b, a >= c, b >= c --> c<= b <= a
- return b;
- }
Partitioning(分割)
- Partitioning
- template <class RandomAccessIterator, class T>
- RandomAccessIterator __unguarded_partition(
- RandomAccessIterator first,
- RandomAccessIterator last,
- T pivot)
- {
- while(true){
- while (*first < pivot) ++first; // first 找到 >= pivot的元素就停
- --last;
- while (pivot < *last) --last; // last 找到 <=pivot
- if (!(first < last)) return first; // 交错,结束循环
- // else
- iter_swap(first,last); // 大小值交换
- ++first; // 调整
- }
- }
三、Heap Sort
- Heap Sort
- // paitial_sort的任务是找出middle - first个最小元素。
- template <class RandomAccessIterator>
- inline void partial_sort(RandomAccessIterator first,
- RandomAccessIterator middle,
- RandomAccessIterator last)
- {
- __partial_sort(first, middle, last, value_type(first));
- }
- template <class RandomAccessIterator,class T>
- inline void __partial_sort(RandomAccessIterator first,
- RandomAccessIterator middle,
- RandomAccessIterator last, T*)
- {
- make_heap(first, middle); // 默认是max-heap,即root是最大的
- for (RandomAccessIterator i = middle; i < last; ++i)
- if (*i < *first)
- __pop_heap(first, middle, i, T(*i), distance_type(first));
- sort_heap(first,middle);
- }
四、IntroSort
- Intro Sort
- template <class RandomAccessIterator>
- inline void sort(RandomAccessIterator first,
- RandomAccessIterator last)
- {
- if (first != last){
- __introsort_loop(first, last, value_type(first), __lg(last-first)*2);
- __final_insertion_sort(first,last);
- }
- }
- // __lg()用来控制分割恶化的情况
- // 找出2^k <= n 的最大值,例:n=7得k=2; n=20得k=4
- template<class Size>
- inline Size __lg(Size n)
- {
- Size k;
- for (k = 0; n > 1; n >>= 1)
- ++k;
- return k;
- }
- // 当元素个数为40时,__introsort_loop的最后一个参数
- // 即__lg(last-first)*2是5*2,意思是最多允许分割10层。
- const int __stl_threshold = 16;
- template <class RandomAccessIterator, class T, class Size>
- void __introsort_loop(RandomAccessIterator first,
- RandomAccessIterator last, T*,
- Size depth_limit)
- {
- while (last - first > __stl_threshold){ // > 16
- if (depth_limit == 0){ // 至此,分割恶化
- partial_sort(first, last, last); // 改用 heapsort
- return;
- }
- --depth_limit;
- // 以下是 median-of-3 partition,选择一个够好的枢轴并决定分割点
- // 分割点将落在迭代器cut身上
- RandomAccessIterator cut = __unguarded_partition
- (first, last, T(__median(*first,
- *(first + (last - first)/2),
- *(last - 1))));
- // 对右半段递归进行sort
- __introsort_loop(cut,last,value_type(first), depth_limit);
- last = cut;
- // 现在回到while循环中,准备对左半段递归进行sort
- // 这种写法可读性较差,效率也并没有比较好
- }
- }
- template <class RandomAccessIterator>
- void __final_insertion_sort(RandomAccessIterator first,
- RandomAccessIterator last)
- {
- if (last - first > __stl_threshold){
- // > 16
- // 一、[first,first+16)进行插入排序
- // 二、调用__unguarded_insertion_sort,实质是直接进入插入排序内循环,
- // *参见Insertion sort 源码
- __insertion_sort(first,first + __stl_threshold);
- __unguarded_insertion_sort(first + __stl_threshold, last);
- }
- else
- __insertion_sort(first, last);
- }
- template <class RandomAccessIterator>
- inline void __unguarded_insertion_sort(RandomAccessIterator first,
- RandomAccessIterator last)
- {
- __unguarded_insertion_sort_aux(first, last, value_type(first));
- }
- template <class RandomAccessIterator, class T>
- void __unguarded_insertion_sort_aux(RandomAccessIterator first,
- RandomAccessIterator last,
- T*)
- {
- for (RandomAccessIterator i = first; i != last; ++i)
- __unguarded_linear_insert(i, T(*i));
- }
- if (last - first > __stl_threshold){ // > 16
- ...
- ...
- __introsort_loop(cut,last,value_type(first), depth_limit);
- __introsort_loop(first,cut,value_type(first), depth_limit);

STL sort的更多相关文章
- STL sort 函数实现详解
作者:fengcc 原创作品 转载请注明出处 前几天阿里电话一面,被问到STL中sort函数的实现.以前没有仔细探究过,听人说是快速排序,于是回答说用快速排序实现的,但听电话另一端面试官的声音,感觉不 ...
- STL sort()函数
C++之所以得到这么多人的喜欢,是因为它既具有面向对象的概念,又保持了C语言高效的特点.STL 排序算法同样需要保持高效.因此,对于不同的需求,STL提供的不同的函数,不同的函数,实现的算法又不尽相同 ...
- STL::sort函数实现
声明:本文参考链接:STL::sort实现. 排序是面试中经常被问及的算法基础知识点,虽然实际应用中不会直接使用,但是理解这些简单的算法知识对于更复杂更实用的算法有一定的帮助,毕竟面试总不能问的太过深 ...
- STL sort 函数实现详解 ZZ
前几天阿里电话一面,被问到STL中sort函数的实现.以前没有仔细探究过,听人说是快速排序,于是回答说用快速排序实现的,但听电话另一端面试官的声音,感觉不对劲,知道自己回答错了.这几天特意看了一下,在 ...
- c++ stl sort example
c++ stl sort函数使用举例: #include <iostream> #include<vector> #include<algorithm> #incl ...
- c++ STL sort struct comp
详细解说 STL 排序(Sort) http://www.cppblog.com/mzty/archive/2005/12/15/1770.html 详细解说 STL 排序(Sort) 作者Winte ...
- 分享stl sort函数坑点导致coredump问题
在<Effective STL> 的条款21中就有讨论:永远让比较函数对相同元素返回false! 也就是说在实现stl sort函数自定义比较器时,一定要满足这种严格弱序化的问题.
- STL sort源码剖析
转载自:http://www.cnblogs.com/imAkaka/articles/2407877.html STL的sort()算法,数据量大时采用Quick Sort,分段递归排序,一旦分段后 ...
- STL——sort函数简介
参考:http://blog.csdn.net/s030501408/article/details/5329477 0)与C标准库qsort的比较:http://bbs.csdn.net/topic ...
随机推荐
- intellij 出现“Usage of API documented as @since 1.6+”的解决办法(转)
原文链接:http://www.cnblogs.com/cxj20160928/p/5954196.html intellij 出现“Usage of API documented as @since ...
- 概念:GNU构建系统和Autotool
经常使用Linux的开发人员或者运维人员,可能对configure->make->make install相当熟悉.事实上,这叫GNU构建系统,利用脚本和make程序在特定平台上构建软件. ...
- free和delete把指针怎么啦?
别看free和delete的名字恶狠狠的(尤其是delete),它们只是把指针所指的内存给释放掉,但并没有把指针本身干掉. 用调试器跟踪示例7-5,发现指针p被free以后其地址仍然不变(非NULL) ...
- (转)MapReduce Design Patterns(chapter 7 (part 2))(十四)
External Source Input Pattern Description 这种模式不从hdfs加载数据,而是从hadoop以外系统,例如RDB或web service加载. Intent 想 ...
- Vue(2) : Vue for Gank.io
简介 最近学习Vue2.0,由于不懂前端知识,学习过程比较缓慢.文档学习过程如下: 通读vue官文 通读vue-router 2中文指南 学习axios 通读vuex官文 数据接口 再次感谢代码家的G ...
- Jira简单使用操作指引20150605
1.选择项目 2.点击[问题]——>[所有问题] 3.选择状态(一般开发关注[新增.处理中],测试关注[已解决.已作废]) 4.选择[more],勾选[解决版本].[影响版本].[解决人],我们 ...
- Linux下打开windows中文文本乱码问题
1. 查看文件的编码方式:file命令 $ file test_file.txt test_file.txt: ISO- text, with very long lines $ file train ...
- IOS开发 ARC和非ARC下使用Block属性的问题
1. Block的声明和线程安全 Block属性的声明,首先需要用copy修饰符,因为只有copy后的Block才会在堆中,栈中的Block的生命周期是和栈绑定的,可以参考之前的文章(iOS: 非AR ...
- linux前奏
1:选典型 2:选稍后自定义安装系统 3: 4: :5:弹出清单 二:装系统 下载linux的网址:https://mirrors.aliyun.com/centos/ 1: 2: 3: 2:如何修改 ...
- Uncaught TypeError: jQuery.i18n.browserLang is not a function
/********************************************************************* * Uncaught TypeError: jQuery. ...