排序函数
排序在ACM题中经常使用到。
排序有很多种算法,例如:冒泡:O(n^2)排序,不但程序容易超时,而且浪费宝贵的比赛时间,还很有可能写错.
这里说到的是排序函数,即可以直接调用的函数。
sort的用法:
sort----复杂度为n*log2(n)
第一个参数是要排序的区间首地址,第二个参数是区间尾地址的下一地址。也就是说,排序的区间是[a,b)
#include<stdio.h>的情况下
使用时得注明:
using namespace std;或直接打std::sort()还得加上#include<algorithm>
例:
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
int a[20];
for(int i=0;i<20;++i)
cin>>a[i];
sort(a,a+20);
//范围,很明显这里是a+20注意,这是必要的,如果是a+19
for(i=0;i<20;i++)
//最后一个值a[19]就不会参与排序。
cout<<a[i]<<endl;
return 0;
}
默认sort排序后是升序,如果想让他降序排列,可以使用自己编的cmp函数
bool compare(int a,int b){
return a>b;
//降序排列,如果改为
return a<b;,则为升序
}
sort(*a,*b,cmp);
假设自己定义了一个结构体node
struct node{
int a;
int b;
double c;
}
有一个node类型的数组node arr[100],想对它进行排序:先按a值升序排列,如果a值相同,再按b值降序排列,如果b还相同,就按c降序排列。就可以写这样一个比较函数:
以下是代码片段:
bool cmp(node x,node y)
{
if(x.a!=y.a) return x.a
if(x.b!=y.b) return x.b>y.b;
return return x.c>y.c;
} 排序时写sort(arr,a+100,cmp);
qsort的用法
一、对int类型数组排序
int num[100];
int cmp(const void *a,const void *b){
return *(int*)a-*(int*)b;
}
qsort(num,100,sizeof(num[0]),cmp);
可见:参数列表是两个空指针,现在他要去指向你的数组元素。所以转型为你当前的类型,然后取值。升序排列时,若第一个参数指针指向的“值”大于第二个参数指针指向的“值”
,则返回正;若第一个参数指针指向的“值”等于第二个参数指针指向的“值”,则返回零;若第一个参数指针指向的“值”小于第二个参数指针指向的“值”,则返回负;
二维数组(只对数排序,例如:坐标下不同的数):
int cmp(const void *a,const void *b){
return *(int*)a-*(int*)b;
}
qsort(a,4,sizeof(a[0][0]),cmp);
二、对char类型数组排序(同int类型)
char word[100];
int cmp(const void *a,const void *b){
return *(char*)a-*(int*)b;
}
qsort(word,100,sizeof(word[0]),cmp);
三、对double类型数组排序(特别要注意)
double in[100];
int cmp(const void *a,const void *b){
return*(double*)a>*(double*)b?1:-1;
}
qsort(in,100,sizeof(in[0]),cmp);
返回值的问题,显然cmp返回的是一个整型,所以避免double返回小数而被丢失。来一个判断。
四、对结构体一级排序
struct In{
double data;
int other;
}s[100]
//按照data的值从小到大将结构体排序,关于结构体内的排序关键数据data的类型可以很多种,参考上面的例子写
int cmp(const void *a,const void *b){
return(*(In*)a).data>(*(In*)b).data?1:-1;
}
qsort(s,100,sizeof(s[0]),cmp);
五、对结构体二级排序
struct In{
int x;
int y;
}s[100];
//按照x从小到大排序,当x相等时按照y从大到小排序
int cmp(const void *a,const void *b){
struct In *c=(In*)a;
struct In *d=(In*)b;
if(c->x!=d->x)
return c->x-d->x;
else
return d->y-c->y;
}
qsort(s,100,sizeof(s[0]),cmp);
六、对字符串进行排序
struct In{
int data;
char str[100];
}s[100];
//按照结构体中字符串str的字典顺序排序
int cmp(const void *a,const void *b){
return strcmp((*(In*)a)->str,(*(In*)b)->str);
}
qsort(s,100,sizeof(s[0]),cmp);
注意!qsort中的cmp得自己写。
区别:
std::sort是一个改进版的qsort.
sort是qsort的升级版,如果能用sort尽量用sort,使用也比较简单,不像qsort还得自己去写cmp函数,只要注明使用的库函数就可以使用,参数只有两个(如果是普
通用法)头指针和尾指针;
std::sort函数优于qsort的一些特点:
对大数组采取9项取样,更完全的三路划分算法,更细致的对不同数组大小采用不同方法排序。