STL 排序(转载)
这篇文章关于STL中的排序写的虽不深入,但是还是挺好的。
1、sort
sort有两种形式,第一种形式有两个迭代器参数,构成一个前开后闭的区间,按照元素的 less 关系排序;第二种形式多加一个指定排序准则的谓词。sort基本是最通用的排序函数,它使用快速排序算法,并且在递归过程中,当元素数目小于一个阈值(一般是16,我的试验是24)时,转成直接插入排序。伟大的数学家Knuth已经证明,在平均意义上,快速排序是最快的了;当然,最坏复杂性比较差。sort要求随机迭代器,因此对于很多编译器来说,对于前向迭代器(如list)使用sort是一个编译错误。
sort的基本使用方式如下:
#include <vector>
#include <algorithm>
#include <functional>
#include <cstdlib> using namespace std; void func1()
{
vector<int> ar;
//向数组里面插入一些随机数
generate_n(back_inserter(ar), , rand);
//按从小到大排序
sort(ar.begin(), ar.end());
}
逆序排列的方法
void func2()
{
vector<int> ar;
//向数组里面插入一些随机数
generate_n(back_inserter(ar), , rand); //方法1:使用函数作为谓词
sort(ar.begin(), ar.end(), GreateThan);
//方法2:使用仿函数作为谓词
//注意下面两种方法都需要有个括号,实际上是要产生一个临时对象
sort(ar.begin(), ar.end(), CompareInt());
//方法3:使用预定义的Adapter, 定义在 <functional> 中
sort(ar.begin(), ar.end(), greater<int>());
//方法4:正常排序,然后翻转过来
sort(ar.begin(), ar.end());
reverse(ar.begin(), ar.end());
//方法5:使用逆迭代器
sort(ar.rbegin(), ar.rend());
}
2、stable_sort
sort优点一大堆,一个缺点就是它不是一种稳定的排序。什么是排序的稳定性?就是如果出现两个元素相等时,要求排序之后他们之间保持原来的次序(比如我们先按学号排序,然后按成绩排序,这时就希望成绩相同的还是按照学号的次序排)。很可惜,快速排序算法就不是稳定的,要追求这个,只好用stable_sort了。
在各种排序算法中,合并排序是稳定的,但一般的合并排序需要额外的O(N)的存储空间,而这个条件不是一定能够满足的(可能是比较奢侈的)。所以在stable_sort内部,首先判断是否有足够的额外空间(如vecotr中的cap()-size()部分),有的话就使用普通合并函数,总的时间复杂性和快速排序一个数量级,都是O(N*logN)。如果没有额外空间,使用了一个merge_without_buffer的关键函数进行就地合并(如何实现是比较有技巧的,完全可以专门谈一谈),这个合并过程不需要额外的存储空间(递归的堆栈除外),但时间复杂度变成O(N*logN),这种情况下,总的stable_sort时间复杂度是O(N*logN*logN)。
总之,stable_sort稍微慢一点儿,但能够保证稳定,使用方法和sort一样。但很多时候可以不用这种方式和这个函数,比如上面的例子,完全可以在排序比较准则中写入成绩和学号两个条件就OK了。
class CStudent
{
public:
CStudent();
//注意这个比较函数中的const
bool operator<(const CStudent& rhs) const
{
if (m_score != rhs.m_score)
return (m_score <rhs.m_score);
return m_name <rhs.m_name;
}
protected:
std::string m_name;
int m_score;
}; void func4()
{
vector<CStudent> arStu;
sort(arStu.begin(), arStu.end());
}
3、heap_sort
堆排序也是一种快速的排序算法,复杂度也是O(N*logN)。STL中有一些和堆相关的函数,能够构造堆,如果在构造好的堆上每次取出来根节点放在尾部,所有元素循环一遍,最后的结果也就有序了。这就是sort_heap了。它的使用要求区间已经被构造成堆,如:
void func5()
{
vector<int> ar;
//生成数据
generate_n(back_inserter(ar), , rand);
//构造堆
make_heap(ar.begin(), ar.end());
//堆排序
sort_heap(ar.begin(), ar.end());
}
4、list.sort
对于list容器,是不能直接使用sort的(包括stable_sort),从技术的角度来说,sort要求随机迭代器;从算法的角度来说,list这种链表结构本身就不适合用快速排序。因此,list容器内部实现了专门的sort算法,这个算法采用的是合并排序,应该是稳定的(不确定)。如:
list<int> li;
li.sort();
STL 排序(转载)的更多相关文章
- 详细解说 STL 排序(Sort)
0 前言: STL,为什么你必须掌握 对于程序员来说,数据结构是必修的一门课.从查找到排序,从链表到二叉树,几乎所有的算法和原理都需要理解,理解不了也要死记硬背下来.幸运的是这些理论都已经比较成熟,算 ...
- 转:详细解说 STL 排序(Sort)
详细解说 STL 排序(Sort) 详细解说 STL 排序(Sort) 作者Winter 详细解说 STL 排序(Sort) 0 前言: STL,为什么你必须掌握 1 STL提供的Sort 算法 1. ...
- 详细解说 STL 排序(Sort)(转)
作者Winter 详细解说 STL 排序(Sort) 0 前言: STL,为什么你必须掌握 1 STL提供的Sort 算法 1.1 所有sort算法介绍 1.2 sort 中的比较函数 1.3 sor ...
- HDU-1263(STL+排序)
水果 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submiss ...
- Codeforces 997D(STL+排序)
D. Divide by three, multiply by two time limit per test 1 second memory limit per test 256 megabytes ...
- (C++)STL排序函数sort和qsort的用法与区别
主要内容: 1.qsort的用法 2.sort的用法 3.qsort和sort的区别 qsort的用法: 原 型: void qsort(void *base, int nelem, int widt ...
- c++STL排序算法注意事项
关于算法中的比较函数 #include<iostream> #include<algorithm> using namespace std; int compare(doubl ...
- HTML5 进阶系列:拖放 API 实现拖放排序(转载)
HTML5之拖放API实现拖放排序 前言 HTML5 中提供了直接拖放的 API,极大的方便我们实现拖放效果,不需要去写一大堆的 js,只需要通过监听元素的拖放事件就能实现各种拖放功能. 想要拖放某个 ...
- AIM Tech Round 4 (Div. 2)(A,暴力,B,组合数,C,STL+排序)
A. Diversity time limit per test:1 second memory limit per test:256 megabytes input:standard input o ...
随机推荐
- [转]RTH试用手记之“偶发信号观测”
年初,罗德与施瓦茨公司(Rohde & Schwarz)推出了第一款的手持示波器,从指标上看,该示波器打破了传统手持器功能简单.指标水平低.结构粗糙的印象,取而代之达到了主流台式数字示波器的性 ...
- jmeter测试mysql数据库之JDBC请求
所有jmeter基本组件功能本文不做介绍.jmeter要链接mysql数据库,首先得下载mysql jdbc驱动包(注:驱动包的版本一定要与你数据库的版本匹配,驱动版本低于mysql版本有可能会导致连 ...
- C语言/C++编程学习:不做C/C++工作也要学C/C++的原因!
C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现 ...
- UWP开发入门(十)——通过继承来扩展ListView
本篇之所以起这样一个名字,是因为重点并非如何自定义控件,不涉及创建CustomControl和UserControl使用的Template和XAML概念.而是通过继承的方法来扩展一个现有的类,在继承的 ...
- 2018年秋PTA乙级回顾
距离上次我一个人参加PAT考试已经过去快一个学期了,想想上次自己也是搞笑,自己一个人被这个书包就去了ZZ,人生地不熟的,乘坐公交车还坐反了.考完试因为不知道要等到考试结束就可以领取成绩证书,自己连那张 ...
- “全栈2019”Java异常第十三章:访问异常堆栈跟踪信息
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...
- Java - io输入输出流 --转换流
转换流 转换输出流 OutputStreamWriter: 说明: /* * OutputStreamWriter 这个类的作用 * 就是指定输出流的编码格式 * 这个类的构造方法 需要传递 一个输 ...
- JDBC技术(汇聚页)
JDBC代表Java数据库连接(Java Database Connectivity),它是用于Java编程语言和数据库之间的数据库无关连接的标准Java API, 换句话说:JDBC是用于在Java ...
- rpm -ivh 这个ivh是干什么的
安装的时候显示安装进度 --从百度知道复制过来的 RMP 是 LINUX 下的一种软件的可执行程序,你只要安装它就可以了.这种软件安装包通常是一个RPM包(Redhat Linux Packet Ma ...
- Java初学者的学习路线建议
java学习这一部分其实也算是今天的重点,这一部分用来回答很多群里的朋友所问过的问题,那就是我你是如何学习Java的,能不能给点建议?今天我是打算来点干货,因此咱们就不说一些学习方法和技巧了,直接来谈 ...