时隔20多天,本蒟蒻终于记起了他的博客园密码!!!

废话不多说,今天主题:STL快排函数sort()与结构体关键字排序

Part 1:引入和导语

首先,我们需要知道,algorithm库里有一些奇怪的函数。

这些函数可以替代一些代码,使你的程序更加简洁好懂,还可以偷懒。

比如在进行DP时的状态转移时可以用的max()和min()可以快速比较两个数的大小,

又或者是abs(),看似没什么用的绝对值函数,

亦或是lower_bound(),upper_bound()拯救二分渣(比如我)的二分查找函数。

……

等等等等,只有你想不到,没有STL库的函数做不到。

我相信有很多刚开始学排序的同学被一些简单的排序题整的死去活来。明明很简单,代码却难的要死,又臭又长,根本就不想打那么复杂的代码!

而且复杂度不够优秀,更dio更优秀的归并(二分法排序)又不会写,怎么办?

Part 2:简单介绍快速排序——sort()函数

今天主要讲sort()快速排序函数,可以上述问题。

它的复杂度O(nlogn)。

这个复杂度就很优秀,比一般的冒泡,选择,插入排序都要优秀的多。

另外,sort()并不只是单纯的快速排序,他的复杂度不会像手写快速排序那样退化,稳定在O(nlogn)

对于桶,只要数据过大桶就不行了,但是sort可以轻松应对(滑稽)

另外,顺带一提,sort()默认从小到大排序,但是聪明的程序猿们不会让自己的函数这么鸡肋,所以赋予了它更强大的功能……那都是后话,一会我会专门提到。

现在请大家看程序,程序同样简洁优秀。

上基本模板代码,由于我直接sort()快速排序,所以是默认从小到大排。

#include<algorithm>
#include<cstdio>
using namespace std;
int a[];//定义您要排序的数组
int main()
{
for(int i=;i<;i++)
{
scanf("%d",&a[i]);
}
sort(a,a+);//对它进行sort()排序,格式sort(排序数组名字+n,排序数组名字+m,???)
//这里的a是排序对象,+n和+m是指从第n项到第m-1项进行排序。???是重载函数位,一会提到。
for(int i=;i<;i++)
{
printf("%d ",a[i]);//再输出
}
return ;
}

这样就可以方便的对您的数组进行从小到大排序了,唯一要注意的是开STL库<algorithm>

很简洁对吧?但是同样,也很鸡肋,如果我想从大到小排怎么办?

教您一招!

for(int i=;i>=;i--)
{
printf("%d ",a[i]);
}

没错您可以倒着输出!!!(逃)

咳咳!说正经的,到底如何实现从大到小排序呢?

请出我们今天的大部头——cmd重载函数!

Part 3:重载您的快排函数!

吼吼吼!妈妈再也不用担心我的代码又臭又长了!但是还有一个问题没有解决——对于强迫症患者,怎么让它从大到小排序呢?(我就想从第一个元素开始循环我不管!!!)

cmd函数可以满足您的需求(我叫它cmd,dalao们可以取别的高端大气的名字QAQ)

具体如何操作?请康康我的代码。

#include<algorithm>
#include<cstdio>
using namespace std;
int a[];//定义您要排序的数组
bool cmd(int x,int y)//定义一个高端的重载函数名字,后面是两个变量 。注意是bool类型!
{
return x>y;//返回x>y,意思是当输入两个元素的时候,大的在前。(这里x>y和x>=y没有本质区别)
//反之,如果是<号的话,就是小的在前,但是那样就没意义了。
}
int main()
{
for(int i=;i<;i++)
{
scanf("%d",&a[i]);
}
sort(a,a+,cmd);//对它进行sort()排序,格式sort(排序数组名字+n,排序数组名字+m,重载函数名字)
//这里的a是排序对象,+n和+m是指从第n项到第m-1项按重载规则进行排序。
for(int i=;i<;i++)
{
printf("%d ",a[i]);//再输出
}
return ;
}

和第一次给出的代码,只是多了一个cmd函数。

这样我们可以实现从大到小排序了。

其实不仅是从大到小排序,我们还可以干更nb的事情——关键字快速排序。来,同志们看下一part。(吸引读者阅读兴趣)

Part 4:关键字快速排序

有很多优秀(caodan)的题通常是这样的:

给出一堆人的成绩,优先按总分由高到低排序,总分一样按数学成绩由高到低排序(看不起语文英语的魂淡!!!),数学成绩一样再按输入顺序从先到后排序。

dalao们应该一眼就看出这是个结构体的题,只要开结构体就可以轻松AC,但是我们探讨的不是结构体,而是,关键字排序。

如果您使用手写冒泡等排序方法,程序必然非常优秀(caodan)。

刚才那个题是我自己瞎编的一个“经典”关键字排序,用冒泡的程序如下(我自己写了一遍,真是给自己挖坑)。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int chi,mat,eng;
struct STU{
string st;
int tot;
int math;
int num;
}QAQ[];
int main()
{
for(int i=;i<;i++)
{
cin>>QAQ[i].st;
scanf("%d%d%d",&chi,&mat,&eng);
QAQ[i].tot=chi+mat+eng;
QAQ[i].math=mat;
QAQ[i].num=i;
}
for(int i=;i>=;i--)
{
for(int j=;j<i;j++)
{
if(QAQ[j].tot<QAQ[j+].tot)
{
swap(QAQ[j],QAQ[j+]);//总分大的交换总分小的
}
if(QAQ[j].tot==QAQ[j+].tot)//总分一样看数学
{
if(QAQ[j].math<QAQ[j+].math)
{
swap(QAQ[j],QAQ[j+]);//数学大的交换数学小的
}
if(QAQ[j].math==QAQ[j+].math)//数学一样看输入顺序
{
if(QAQ[j].num>QAQ[j+].num)//输入顺序小的交换输入顺序大的
{
swap(QAQ[j],QAQ[j+]);
}
}
}
}
}
for(int i=;i<;i++)
{
cout<<QAQ[i].st<<endl;//输出名字
}
return ;
//欢迎dalao们造数据狙击我,因为没有真题,我不保证程序没有问题!!!
}

如果不用重载快排,很容易造成如上的if套娃情况。

为了拒绝套娃,让您的代码清爽一些,我们选择sort()重载排序。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int chi,mat,eng;
struct STU{
string st;
int tot;
int math;
int num;
}QAQ[];
bool cmp(STU a,STU b)
{
if(a.tot!=b.tot)
{
return a.tot>b.tot;//如果总分不一样,返回较大值
}
else
{
if(a.math!=b.math)
{
return a.math>b.math;//总分一样,数学不一样,返回数学较大值
}
else
{
return a.num<b.num;//数学也一样,返回输入顺序较小值
}
}
}
int main()
{
for(int i=;i<;i++)
{
cin>>QAQ[i].st;
scanf("%d%d%d",&chi,&mat,&eng);
QAQ[i].tot=chi+mat+eng;
QAQ[i].math=mat;
QAQ[i].num=i;
}
sort(QAQ,QAQ+,cmp);//直接排序
for(int i=;i<;i++)
{
cout<<QAQ[i].st<<" ";
}
return ;
}

您看!套娃的次数从5次减少到了2次。(好像没什么大变化啊)

但是,这只是本蒟蒻随便弄的一个题,下面上一个极其简单(caodan)的模拟/排序题。

刚学会的童鞋们建议先不要看,去洛谷找几个简单的关键字排序练习一下,毕竟这个玩意是绿题。

洛谷P1786 :帮贡排序

很显然,这题用手写关键字排序会直接死亡(不排除dalao狙击)

代码下放

//P1786
//#include<zhangtao.std>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char dd[];
struct STU{
int num;
string name;
int pos;
long long score;
int level;
}AK[];
int n;
bool cmp1(STU a,STU b)
{
if(a.score!=b.score)
{
return a.score>b.score;
}
else
{
return a.num<b.num;
}
}
bool cmp2(STU c,STU d)
{
if(c.pos!=d.pos)
{
return c.pos>d.pos;
}
else
{
if(c.level!=d.level)
{
return c.level>d.level;
}
else
{
return c.num<d.num;
}
}
}
int main()
{
cin>>n;
for(int i=;i<n;i++)
{
AK[i].num=i;
cin>>AK[i].name;
scanf("%s",dd);
if(dd[]=='B')
{
if(dd[]=='u')
{
AK[i].pos=;
}
else
{
AK[i].pos=;
}
}
if(dd[]=='F')
{
AK[i].pos=;
}
if(dd[]=='H')
{
AK[i].pos=;
}
if(dd[]=='Z')
{
AK[i].pos=;
}
if(dd[]=='T')
{
AK[i].pos=;
}
if(dd[]=='J')
{
AK[i].pos=;
}
cin>>AK[i].score>>AK[i].level;
if(AK[i].pos==)
{
AK[i].score=;
}
if(AK[i].pos==)
{
AK[i].score=;
}
}
sort(AK,AK+n,cmp1);
for(int i=;i<n;i++)
{
if(<=i&&i<=)
{
AK[i].pos=;
}
if(<=i&&i<=)
{
AK[i].pos=;
}
if(<=i&&i<=)
{
AK[i].pos=;
}
if(<=i&&i<=)
{
AK[i].pos=;
}
if(<=i)
{
AK[i].pos=;
}
}
sort(AK,AK+n,cmp2);
for(int i=;i<n;i++)
{
cout<<AK[i].name;
if(AK[i].pos==)
{
cout<<" BangZhu ";
}
if(AK[i].pos==)
{
cout<<" FuBangZhu ";
}
if(AK[i].pos==)
{
cout<<" HuFa ";
}
if(AK[i].pos==)
{
cout<<" ZhangLao ";
}
if(AK[i].pos==)
{
cout<<" TangZhu ";
}
if(AK[i].pos==)
{
cout<<" JingYing ";
}
if(AK[i].pos==)
{
cout<<" BangZhong ";
}
cout<<AK[i].level<<endl;
}
return ;
}

大家自己领会代码,主要思路就是用数字代替帮会中的位置,然后进行重载运算符,然后关键字排序即可。

今天的分享就到这里,再见dalao们!!!

STL函数库的应用第二弹——快排sort函数与结构体关键字排序的更多相关文章

  1. Android JNI编程(六)——C语言函数指针、Unition联合体、枚举、Typedef别名、结构体、结构体指针

    版权声明:本文出自阿钟的博客,转载请注明出处:http://blog.csdn.net/a_zhon/. 目录(?)[+] 一:函数指针 1.函数指针顾名思义就是定义一个指针变量指向一个函数,和一级指 ...

  2. STL函数库的应用第一弹——数据结构(队列)

    队列是什么? 队列是一种特殊的线性表,特殊之处在于它只允许在表的前端进行删除操作,而在表的后端进行插入操作. 和栈一样,队列是一种操作受限制的线性表.进行插入操作的端称为队尾,进行删除操作的端称为队头 ...

  3. oracle函数、包、变量的定义和使用、重点”结构体和数组”

    函数 实例1:输入雇员的姓名,返回该雇员的年薪 create function fun1(spName varchar2) ,); begin +nvl(comm,) into yearSal fro ...

  4. 快排实现仿order by多字段排序

    class OrderBy(object): def __init__(self, sequence, *condition, **extra_condition): ""&quo ...

  5. STL set容器添加结构体并排序

    #include <iostream> #include <string> #include <cstring> //strcpy #include <cst ...

  6. STL——sort函数简介

    参考:http://blog.csdn.net/s030501408/article/details/5329477 0)与C标准库qsort的比较:http://bbs.csdn.net/topic ...

  7. STL 之 sort 函数使用方法

    关于Sort Sort函数是C++ STL(Standard Template Library / 标准函数库) <algorithm>头文件中的一个排序函数,作用是将一系列数进行排序,因 ...

  8. labview从入门到出家5(进阶篇)--程序调试以及labview函数库的运用

    跟了前面几章的操作流程,相信大家对labview有了一定的认识.其实只要了解了labview的编程思路,再熟悉地运用各个变量,函数以及属性,那么我们就可以打开labview的大门了.跟其他编程语言一样 ...

  9. F2833x 调用DSP函数库实现复数的FFT的方法

    转载自:http://blog.csdn.net/aeecren/article/details/67644363:个人觉得写的很详细,值得一看 在数字信号处理中,FFT变换是经常使用到的,在DSP中 ...

随机推荐

  1. 01 安装Linux虚拟机

    平常的工作学习中,Linux成为了一项比不可少的需要的掌握的技能,但是大部分人又不习惯于使用Linux进行生活,所以你需要在你的Windows电脑上安装一个虚拟机,那如何安装呢?其实不难,跟着我一步步 ...

  2. git安装并与远程仓库关联相关配置

    git是当前最流行的版本控制系统,下面简单记录一下git的安装及其与远程仓库的关联. git安装 打开git官网,下载对应的安装包. 双击运行安装包,安装过程中可以直接选择默认配置,一路next下去. ...

  3. js原型链结构理解

    在一般的面向对象的语言中,都存在类(class)的概念,类就是对象的模板,对象就是类的实例. 但在js中是没有类的定义的(万物皆是对象).  题外话:但是在ES6中提供了更接近传统语言的写法,引入了C ...

  4. redis基本操作介绍

    一.字符串 单个设置:set key value,如果key不存在则设置键值对,如果存在则修改 批量设置:mset key1 value1 [key2 value2] 单个获取:get key,如果k ...

  5. Fortify Audit Workbench 笔记 Race Condition: Singleton Member Field 竞争条件:单例的成员字段

    Race Condition: Singleton Member Field 竞争条件:单例的成员字段 Abstract Servlet 成员字段可能允许一个用户查看其他用户的数据. Explanat ...

  6. I Hate It(区间最大问题,线段树)

    很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问.当然,老师有时 ...

  7. Python os.pathconf() 方法

    概述 os.pathconf() 方法用于返回一个打开的文件的系统配置信息.高佣联盟 www.cgewang.com Unix 平台下可用. 语法 fpathconf()方法语法格式如下: os.fp ...

  8. Python os.fchown() 方法

    概述 os.fchown() 方法用于修改一个文件的所有权,这个函数修改一个文件的用户ID和用户组ID,该文件由文件描述符fd指定.高佣联盟 www.cgewang.com Unix上可用. 语法 f ...

  9. 下载excel模板,导入数据时需要用到

    页面代码: <form id="form1" enctype="multipart/form-data"> <div style=" ...

  10. php+mysql+apache实现登录注册系统

    Php+mysql写网页注册登录系统 1.搭建msyql+php+apache的网站环境 (1) 在云服务器上搭建服务器,推荐使用宝塔集成 (2) 在本地windows搭建,推荐自己采用分开安装,这样 ...