STL-sort学习
学习sort发现不错的文章,摘录一下。
并且做一个自己的理解,默认的sort下排序,即升序。
前景知识 三种排序
快速排序:视频入口 B站的视频,简单的讲了一下快排,并且手把手的带你简单的实现了一遍。
优化:优化参考1 优化参考2
1.三数取中法,在头元素,尾元素,中间元素上,取得中位数。
2.随机选取基准,用随机数代替基准点。
3.插排的引入,当递归到一定程度后,last和first中间元素个数不多,并且已经基本有序,改用插排。
1 | int n = 1000,a[1000]; |
插入排序:很简单的东西,要多说一点的是,
它在数据大致有序的情况表现非常好,可以达到O(N)。
参考入口地址 虽然笔者是Java的,不过丝毫不影响对思路的理解
1 | int a[1000]; |
堆排序:B站视频入口 讲得很好,也是一样,讲完原理之后敲代码了。
1 | int n=1000,tree[1000] = {1,7,4,5,8,9,6,3,2,0}; |
sort
参考网址入口 这篇是我见过写的最好的了。没有找到侯捷老师的视频。
以下很多引用自原文:
(1)在数据量很大时采用正常的快速排序,此时效率为O(logN)。//最好情况
(2)一旦分段后的数据量小于某个阈值,就改用插入排序,因为此时这个分段是基本有序的,这时效率可达O(N)。//最好情况
(3)在递归过程中,如果递归层次过深,分割行为有恶化倾向时,它能够自动侦测出来,使用堆排序来处理,在此情况下,使其效率维持在堆排序的O(N logN),但这又比一开始使用堆排序好。
1 | // 1 sort() |
1 | // 2 __introsort_loop() |
1 | // 3 __unguarded_partition() 快排 |
1 | // 4 partial_sort()和__partial_sort() 堆排 |
1 | // 5 __final_insertion_sort()------------------>__unguarded_linear_insert() |
万事具备
学了,那就自己敲一下吧,用数组简单实现
1 | //先是写了快排 第一版本 |
1 | //堆排测试 __begin() |
1 | //插排的整合之后再更新 |
看完之后,这里我有两个问题,
1.就是(2)一旦分段后的数据量小于某个阈值,就改用插入排序,因为此时这个分段是基本有序的,这时效率可达O(N)。
这个到底是什么意思,是a[15]的时候直接调用插排,还是说a[10000]在快排递归,区段小于16的时候调用插排。如果是第二种,插排是在sort()函数里面的,也就是说在introsort_loop()执行完之后才开始调用。如果他是在intro_loop()函数里调用了,那我认为要在while(){}后面加上插排的调用代码。
2.还有,插排的里是分段的,>16是一段,小于是一段,分段处理。从introsort_loop()出来之后肯定是<=16的,为什么要分这个段呢,没必要啊。我的想法是这个插排的函数不只是由sort()调用,其他也会调用这个函数,所以才这么写
希望解答…….
本文是自己的学习记录,读者可参考,仅供参考
不完善的地方请指正
欢迎来小站一逛 戳一下