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);