STL中排序函数的用法(Qsort,Sort,Stable_sort,Partial_sort,List::sort)
都知道排序很重要,也学了各式各样的排序算法,冒泡、插入、归并等等,但其实在ACM比赛中,只要不是太慢的算法,都可以适用(除非某些题目卡时间卡的很死),这个时候,速度与技巧便成了关键,而在C++的标准库中,就已经定义好了一些排序函数,下面来一一介绍它们吧=7=
Qsort
函数原型为void qsort(void*base,size_t num,size_t width,int(__cdecl*compare)(const void*,const void*));包含四个参数,分别是待排序数组首地址、数组中待排序元素数量、各元素的占用空间大小、指向函数的指针(就是自己的排序函数),这个函数在C语言中就可以使用了,可以不包含第四个参数进行对数组的排序,此时系统会自动按照从小到大的排序,例如:
- int a[] = {,,,,,,};
- qsort(a,,sizeof(a[]));
- //结果:1 2 3 4 5 6 7
好,那么qsort如何对结构体进行排序呢,我们知道,对结构体数组的排序需要自己写一个排序函数,但是和其他函数不一样的是,qsort的排序函数有其固定的形式,例如:
- struct node{
- int id,num;
- }a[] = {{,},{,},{,},{,},{,},{,}};
- int cmp(const void *a,const void *b){
- node *aa = (node *)a;
- node *bb = (node *)b;
- if(aa->num == bb->num){
- return aa->id < bb->id;
- }
- return aa->num > bb->num; //按num值升序排序
- }
- qsort(a,,sizeof(a[]),cmp);
可以看到,cmp函数形参不能直接定义为相应类型,只能定义为const void *p 类型,然后强制转换为相应类型再做出处理。真是因为如此,我们在ACM中不会太经常也不建议用qsort函数,但还是得明白一下操作。
Sort
这个函数相信大家都很熟悉了,就是常用排序函数,给给定区间内进行排序,时间复杂度为O(N*logN),参数有三个,分别是首地址、末地址和排序函数,第三个参数省略时按照从小到大排序,例如:
- int a[] = {,,,,,};
- sort(a,a+);
- //排序结果: 1 2 3 4 5 6
稍微难一点的就是对结构体数组进行排序,此时,sort函数就有多种选择方式了,可以在结构体内重载操作符,写比较函数或者仿函数等都可以,例如:
- struct node{
- int id,num;
- //重载比较符
- bool operator < (const node &b) const{
- if(num == b.num){
- return id < b.id;
- }
- return num > b.num;
- }
- }a[] = {{,},{,},{,},{,},{,},{,}};
- //编写比较函数
- int cmp(node &a,node &b){
- if(a.num == b.num){
- return a.id < b.id;
- }
- return a.num > b.num;
- }
- sort(a,a+); //重载比较符
- sort(a,a+,cmp); //编写比较函数
不使用结构体,使用仿函数就是:
- //编写仿函数
- class CMP{
- public:
- CMP(int _id,int _num):id(_id),num(_num){}
- int id;
- int num;
- bool operator < (const node &b) const{
- if(num == b.num){
- return id < b.id;
- }
- return num > b.num;
- }
- };
- vector<CMP>a;
- sort(a,a+);
基本上Sort的操作就是这些了。
Stable_sort
其实你会发现不仅仅sort有stable_sort,partition也有stable_partition,我们都知道sort是一个不稳定的排序,但stable_sort就是如字面意思一样,是一个稳定的sort排序,那么你可能有疑问,排序后,相同的元素会在一起,稳定不稳定不都是一样的么,如果你存在这个疑问的话,那就肯定还是做题力度不够=7=,你只想到了对元素表面的排序,如果是对元素的某种性质排序呢,例如:
- string s[] = {"spring","lip","eye","winter"};
- bool cmp(string a, string b){
- return a.size() < b.size();
- }
- sort(s,s+,cmp);
对于这段代码,"lip"和"eye"对于比较函数来说是相等的,所以排序后结果可能lip在eye的前面也可能在eye后面,但是如果这里使用stable_sort,排序前lip在eye前面,不管排序次数如何,lip一定会排在eye的前面。
其他用法和sort一样。
Partial_sort
和字面意思一样,部分排序,函数有三个参数,分别是区间要排序的首位置、要排序的末位置以及区间末位置,函数的作用就是把区间内前n个元素排序,其他元素则依次排在末尾,例如:
- int a[] = {,,,,,};
- partial_sort(a,a+,a+);
- //排序结果: 1 2 3 6 5 4
函数其他用法和sort相同,也就没什么好讲的=7=
List::sort
这个是list容器中专有的排序函数,直接对迭代器操作,使用方式为:
- list<int>a;
- a.sort();
那么全部的排序函数已经讲完了,如果在之前你只知道一个sort或者qsort的话,是不是突然觉得知道了很多新东西呢,其实STL的东西远不止这些,学好了STL,对于我们做题真的是有质和速度的双从提升。
还有就是文中提及的仿函数,这个东西也是STL里面的一大类,会专门将这个的,嘻嘻。
后记:有人和我说nth_element函数的讲解,但是nth_element并不算是排序函数,所以没有写在这里,都会写的=7=
STL中排序函数的用法(Qsort,Sort,Stable_sort,Partial_sort,List::sort)的更多相关文章
- Python中排序函数sorted和排序方法sort的异同点对比分析
Python中对序列进行排序有两种方法,一种是使用python内置的全局sorted函数,另一种是使用序列内置的sort方法. 一. 两者相同点 在支持sort方法的序列中都可以对序列进行排序: 二者 ...
- STL中mem_fun, mem_fun_ref用法
1.引言 先看一个STL中for_each的用法: #include <iostream> #include <vector> #include <algorithm&g ...
- C++STL库常用函数用法
开学就要上OOP了.....感觉十分萌萌哒- -! 整理自<ACM程序设计>,本文为转载(原文地址) 迭代器(iterator) 个人理解就是把所有和迭代有关的东西给抽象出来的,不管是数组 ...
- STL之sstream的用法
STL之sstream的用法 说在前面: 库定义了三种类:istringstream.ostringstream和stringstream,分别用来进行流的输入.输出和输入输出操作.另外,每个类都有一 ...
- leetcode 280.Wiggle Sort 、324. Wiggle Sort II
Wiggle Sort: 注意:解法一是每次i增加2,题目不是保证3个3个的情况,而是整个数组都要满足要求. 解法一错误版本: 如果nums的长度是4,这种情况下nums[i+1]会越界.但是如果你用 ...
- 跳跃空间(链表)排序 选择排序(selection sort),插入排序(insertion sort)
跳跃空间(链表)排序 选择排序(selection sort),插入排序(insertion sort) 选择排序(selection sort) 算法原理:有一筐苹果,先挑出最大的一个放在最后,然后 ...
- 连续线性空间排序 起泡排序(bubble sort),归并排序(merge sort)
连续线性空间排序 起泡排序(bubble sort),归并排序(merge sort) 1,起泡排序(bubble sort),大致有三种算法 基本版,全扫描. 提前终止版,如果发现前区里没有发生交换 ...
- java中排序函数sort()使用,Arrays.sort()和Collections.sort()
Java中常用的数组或集合排序的方法有两个,一个是java.util.Arrays中的静态方法Arrays.sort(),还有一个是java.util.Collections中的静态方法的Collec ...
- STL——map/unordered_map基础用法
map /multimap map是STL里重要容器之一. 它的特性总结来讲就是:所有元素都会根据元素的键值key自动排序(也可根据自定义的仿函数进行自定义排序),其中的每个元素都是<key, ...
随机推荐
- 洛谷 P3870 [TJOI2009]开关
题意简述 有n盏灯,默认为关,有两个操作: 1.改变l~r的灯的状态(把开着的灯关上,关着的灯打开) 2.查询l~r开着的灯的数量 题解思路 维护一个线段树,支持区间修改,区间查询 懒标记每次^1 代 ...
- 002——Netty之Netty介绍
Netty出现背景 Java NIO难用 据说存在bug 业界其他NIO框架不成熟 Netty主要解决两个相应关注领域 (1)异步和事件驱动的实现. (2)一组设计模式,将应用逻辑与网络层解耦. 特性 ...
- 【数据结构】线段树(Segment Tree)
假设我们现在拿到了一个非常大的数组,对于这个数组里面的数字要反复不断地做两个操作. 1.(query)随机在这个数组中选一个区间,求出这个区间所有数的和. 2.(update)不断地随机修改这个数组中 ...
- HTML文件上传与下载
文件下载 传统的文件下载有两种方法: 使用<a/>标签,href属性直接连接到服务器的文件路径 window.location.href="url" 这两种方法效果一样 ...
- Protocol, Delegate
协议的构成: 协议:用来指定代理双方可以做什么,必须做什么. 代理:根据指定的协议,完成委托方需要实现的功能. 委托:根据指定的协议,指定代理去完成什么功能. 协议的修饰符: 协议有两个修饰符@opt ...
- Flink的JobManager启动(源码分析)
都知道Flink中的角色分为Jobmanager,TaskManger 在启动脚本里面已经找到了jobmanager的启动类org.apache.flink.runtime.entrypoint.St ...
- 常见rpm包和yum包命令
1.rpm包 在 安装.升级.卸载服务程序时要考虑到其他程序.库的依赖关系,在进行校验.安装. 卸载.查询.升级等管理软件操作时难度都非常大. RPM 机制则为解决这些问题而设计的.RPM 有点像 W ...
- H5 API drawImage的参数
drawImage(this,120,0,180,150,0,0,180,150); //mg图片上的x坐标 img图片上的y坐标 剪切的宽 剪切的高 在canvas上的x坐标 在canvas上的y坐 ...
- 【阿里云IoT+YF3300】4.Alink物模型之事件触发
名词解释:设备的功能模型之一,设备运行时的事件,事件一般包含需要被外部感知和处理的通知信息,可包含多个输出参数.如,某项任务完成的信息,或者设备发生故障或告警时的温度等,事件可以被订阅和推送. 在工控 ...
- Excel VBA 在保留原单元格数据的情况下,将计算的百分比加在后面
算的是红框占绿框的百分比 难点在保留原数据的情况下,把百分比加在后面.通过公式我是不会,但程序实现也不难. 先在Excel中的开发工具中打开visual basic,或者用宏也可以 导入代码文件,代码 ...