sort函数用法(详细),cmp的构造

sort函数

sort是c++STL标准库中提到的基于快速排序的排序函数,在做题的时候使用sort函数很方便,使用sort要使用#include<algorithm>

快速排序具有不稳定性

不稳定性是指,对于指定区域内相等的元素,sort函数可能无法保证数据的元素不发生相对位置不发生改变。

这对于普通的排序问题可能没有影响,比如对于

  2 2 3 1 5

  排序后

1 2 2 3 1 5 (排序前第一个二可能在这里是第二个2)

但是在这里,这些2么有其他含义,对题解影响不大

!!!但是要注意

假如上述两个2风别代表月份和日

那这里可能就会产生歧义

c++中其他有关排序的函数

sort (first, last,cmp)// 对容器或普通数组中 [first, last) 范围内的元素进行排序,默认进行升序排序。

stable_sort (first, last) // 和 sort() 函数功能相似,不同之处在于,对于 [first, last) 范围内值相同的元素,该函数不会改变它们的相对位置。

partial_sort (first, middle, last)// 从 [first,last) 范围内,筛选出 muddle-first 个最小的元素并排序存放在 [first,middle) 区间中。

partial_sort_copy (first, last, result_first, result_last)// 从

[first, last) 范围内筛选出 result_last-result_first 个元素排序并存储到 [result_first,

result_last) 指定的范围中。

is_sorted (first, last)// 检测 [first, last) 范围内是否已经排好序,默认检测是否按升序排序。

is_sorted_until (first, last)// 和 is_sorted() 函数功能类似,唯一的区别在于,如果 [first, last) 范围的元素没有排好序,则该函数会返回一个指向首个不遵循排序规则的元素的迭代器。

void nth_element (first, nth, last)// 找到 [first, last)

范围内按照排序规则(默认按照升序排序)应该位于第 nth

个位置处的元素,并将其放置到此位置。同时使该位置左侧的所有元素都比其存放的元素小,该位置右侧的所有元素都比其存放的元素大。

sort可以排序的对象:

数组(sort函数的cmp不是必须的,不写默认升序排序)

结构体

什么样的元素可以接受sort函数排序

元素类型接受使用>或<运算符

只能对vector,array,deque这三个容器进行排序

cmp函数的使用

sort函数在不使用 cmp函数下,默认使用升序排序的cmp函数

升序:

```

#include<cstdio>

#include<algorithm>

using namespace std;

bool cmp1(int i,int j)

{

return i>j;//i>j返回值是bool类型,true/flase,可以用1/0来代替,假如t1表示x,y不需要互换,假如是0则需要互换.所以这里也可以这样写

/*if(i>j)

return 1;//前面的数大,不换

else if(i<=j)//换

return 0;

*/

}

int main()

{

int a[100]={1, 51 , 65 , 1 , 8 , 9 , 8 , 52 , 89 , 21 };

sort(a,a+100,cmp1);

for(int i=0;i<100;i++)

printf("%d ",a[i]);

}

```

降序:

```

同理:

bool cmp2(int i,int j)

{

 return i<j;

/*if (i>j)

return 0;

else if(i<=j)

return 1;*/

}

```

对n个元素的a数组:sort(a,a+n,cmp)

#### 对结构体进行排序

对结构体排序要构造cmp函数

```bash

#include<cstdio>

#include<algorithm>

#include<string.h>

using namespace std;

struct student{

int id;

int score;

}p[10];

bool cmp3(struct student i,struct student j)

{

return i.score>j.score;

}

int main()

{

for(int i=0;i<10;i++)

scanf("%d %d",&p[i].id,&p[i].score);

sort(p,p+10,cmp3);

for(int i=0;i<10;i++)

printf("id:%d score%d\n",p[i].id,p[i].score);

return 0;

}

```

结构体数组使用sort排序和数组排序很相似

对于cmp:使用

bool (struct 结构体 结构体变量名,struct 结构体 结构体变量名)

{

return 结构体1.待排序变量>或<结构体2.待排序变量

}

!!很多题目不会让你只对于结构体内的某个变量进行单调排序,很可能会有其他限制条件,Eg:对成绩排序还要考虑相同成绩要排姓名首字母的问题,再比如排序生日需要排序年月日。

下面用洛谷P1104题目进行示范

cjf君想调查学校OI组每个同学的生日,并按照从大到小的顺序排序。但cjf君最近作业很多,没有时间,所以请你帮她排序。

输入:人数   

姓名 年 月 日

例:

3

Yangchu 1992 4 23

Qiujingya 1993 10 13

Luowen 1991 8 1

输出:

Luowen

Yangchu

Qiujingya

分析:需要对年月日排序,先排年,年同再排月,月相同再排日:

```bash

#include<cstdio>

#include<string.h>

#include<algorithm>

using namespace std;

struct struct{

int id;

char s[20];

int y;

int m;

int d;

}p[100];

bool cmp(mate a,mate b)

{

if(a.y<b.y)return 1;//先比年,前面小于后面就不换,因为前面老

if(a.y>b.y)return 0;//前面年数大,换

if(a.y==b.y)

{

if(a.m<b.m)return 1;//再比月

if(a.m>b.m)return 0;

if(a.m==b.m)

{

if(a.d<b.d)return 1;//再比日

if(a.d>b.d)return 0;

if(a.d==b.d)

{

if(a.id>b.id)return 1;//最后比编号

else return 0;

}

}

}

}

int main()

{

int n;

scanf("%d",&n);

for(int i=0;i<n;i++)

{

scanf("%s %d %d %d",&p[i].s,&p[i].y,&p[i].m,&p[i].d);

p[i].id=i;

}

sort(p,p+n,cmp);

for(int i=0;i<n;i++)

{

if(i<n-1)

printf("%s\n",p[i].s);

else

printf("%s",p[i].s);

}

return 0;

}

```

分析:简而言之,谁老谁在先,就是排年,年数小就老,年同然后接着比月,月同再比日

对于上文提及的快速排序的不稳定性,可以使用stable_sort函数,不会改变相等元素的位置

题目:洛谷P5740

>

现有 N(N≤1000) 名同学参加了期末考试,并且获得了每名同学的信息:姓名(不超过 8

个字符的字符串,没有空格)、语文、数学、英语成绩(均为不超过 150

的自然数)。总分最高的学生就是最厉害的,请输出最厉害的学生各项信息(姓名、各科成绩)。如果有多个总分相同的学生,输出靠前的那位。

>eg:输入 3             

senpai 114 51 4

lxl 114 10 23

fafa 51 42 60

输出

senpai 114 51 4

此题用结构体很方便,在获取分数的时候把总分存入结构体内,然后对结构体排序,输出第一个,这里最好使用stable_sort,因为可能存在同分数的情况,此时要输入靠前的,这里用stable_sort很方便

迟到的代码

```c

#include<stdio.h>

#include<algorithm>

using namespace std;

struct stu{

char a[10];

int chinese;

int math;

int english;

int score;

}p[1005];

bool cmp(struct stu x,struct stu y)

{

return x.score>y.score;

}

int main()

{

int n;

scanf("%d",&n);

for(int i=0;i<n;i++)

{

scanf("%s %d %d %d",p[i].a,&p[i].chinese,&p[i].english,&p[i].math);

p[i].score=p[i].chinese+p[i].english+p[i].math;

}

stable_sort(p,p+1005,cmp);

printf("%s %d %d %d",p[0].a,p[0].chinese,p[0].english,p[0].math);

return 0;

}

```

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351

推荐阅读更多精彩内容