acm做题过程中经常要用到排序,一般都选用快排,在此对快排做个总结
其中代码用c表示
一.总结
#include<stdio.h>
#include<stdlib.h> //必须包含该头文件
struct 结构体类型名 //数据类型=“struct”+“空格”+“结构体类型名”
{
数据类型1 变量名1;
数据类型2 变量名2; //若要使用结构快排,结构体一定要定义在快排前面
}数组名[数组大小];
int 自定义函数名字(const void *a,const void *b)
{
return(*(数据类型 *)a)>(*(数据类型 *)b)?1:-1; //从小到大进行排序(从大到小排序只要把“>”换成“<”即可)
}
qsort(数组名,数组大小,sizeof(数据类型),自定义函数名字); //调用快排(写在调用的地方)
下面是一些具体的例子
二. 对于普通数组进行快排
1.qsort函数
#include<stdio.h>
#include<stdlib.h>
int cmp(const void *a,const void *b)
{
return(*(int *)a)>(*(int *)b)?1:-1; //对int型数组从小到大进行排序
}
qsort(p,n,sizeof(int),cmp); //调用快排(其中p是int型数组名,n是数组长度)
2.sort函数
同样c++的STL库中也提供了sort排序函数,可以直接拿来使用。在一些题目中,使用上述方法所导致的超时往往换成sort函数即可解决
①sort是一个改进版的qsort. std::sort函数,实验证明sort一般要快于qsort
②优于qsort的一些特点:对大数组采取9项取样,更完全的三路划分算法,更细致的对不同数组大小采用不同方法排序。
③sort是qsort的升级版,如果能用sort尽量用sort,使用也比较简单,不像qsort还得自己去写 cmp 函数
代码如下:
#include<stdio.h>
#include <algorithm> //必须包含该头文件
using namespace std;
int main()
{
int p[10];
int i;
for(i=0;i<10;i++)
scanf("%d",&p[i]);
sort(p,p+10); //调用从小到大快排(p是数组名,p+10中10表示数组长度)
for(i=0;i<10;i++)
printf("%d ",p[i]);
return 0;
}
#include<stdio.h>
#include <algorithm> //必须包含该头文件
#include<functional> //必须包含该头文件
using namespace std;
int main()
{
int p[20];
int i;
for(i=0;i<10;i++)
scanf("%d",&p[i]);
sort(p,p+10,greater<int>()); //调用从大到小快排(p是数组名,p+10中10表示数组长度)
for(i=0;i<10;i++)
printf("%d ",p[i]);
return 0;
}
三.以绝对值排序,按真实值输出
#include<math.h>
#include<stdlib.h>
int cmp(const void *a,const void *b)
{
return abs(*(int *)a)>abs(*(int *)b)?1:-1; //abs函数求绝对值
}
qsort(p,n,sizeof(int),cmp);
四.对于字符串进行快排
1.以升序
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct stu //将字符串存到结构体中的q域
{
char q[50];
}p[1005];
int cmp(const void *a,const void *b) //结构体数组p中,以其成员字符串q为关键字,对p从小到大进行排序
{
if(strcmp((*(struct stu*)a).q,(*(struct stu*)b).q)>=0)
return 1;
else if(strcmp((*(struct stu*)a).q,(*(struct stu*)b).q)<0)
return -1;
return 0;
}
qsort(p,n,sizeof(struct stu),cmp); //调用快排(其中p是struct stu型数组名,n是数组长度)
2.以降序
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct stu
{
char q[50];
}p[1005];
int cmp(const void *a,const void *b) //结构体数组p中,以其成员字符串q为关键字,对p从大到小进行排序
{
if(strcmp((*(struct stu*)a).q,(*(struct stu*)b).q)>=0)
return -1;
else if(strcmp((*(struct stu*)a).q,(*(struct stu*)b).q)<0)
return 1;
return 0;
}
qsort(p,n,sizeof(struct stu),cmp);
五.对于多级结构体数组进行快排
1.对于一级
#include<stdio.h>
#include<stdlib.h>
struct stu
{
int a;
int b;
}p[1005];
int cmp(const void *a,const void *b)
{
return(*(struct stu*)a).b<(*(struct stu*)b).b?1:-1; //结构体数组p中,以其成员b为关键字,对p从大到小进行排序
}
qsort(p,n,sizeof(struct stu),cmp);
2.对于多级(在此以二级为例)
#include<stdio.h>
#include<stdlib.h>
struct stu
{
int a;
int b;
}p[1005];
int cmp(const void *a,const void *b) //结构体数组p中,以其成员a为关键字,对p从大到小进行排序
{
if((*(struct stu*)a).a==(*(struct stu*)b).a)
return(*(struct stu*)a).b<(*(struct stu*)b).b?1:-1; //若p中任意两p[i]的成员a相等,则再以其两的成员b为关键字从大到小排序
else
return(*(struct stu*)a).a<(*(struct stu*)b).a?1:-1;
}
qsort(p,n,sizeof(struct stu),cmp);