找工作做笔试题及面试或参加竞赛的时候,每个人都会遇到需要排序的题目。排序是一种经常要用到的操作。如果每次都自己写个冒泡之类的O(n^2)排序,不但程序容易超时,而且浪费宝贵的比赛时间,还很有可能写错。STL里面有个sort函数,可以直接对数组排序,复杂度为n*log2(n)。使用这个函数,需要包含头文件#inlcude<algorithm>。
下面就来说说sort函数的基本原理,最后再以两个完整的程序结束:
排序的区间可以必须是通过迭代器遍历的(当然数组下标也算),迭代器的类型为随机迭代器;
bool cmp(int a,int b)
{
return a>b;
}</span>
struct node{
int a;
int b;
double 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;
}
下面来看一个完整的例子,题目为“文件名排序 ”。以下是程序代码:
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
//定义一个结构体来表示文件,a代表文件名,b代表文件类型(要么"File"要么"Dir")
struct node{
string a,b;
};
//ASCII码中,所有大写字母排在所有小写字母前面,'A'<'Z'<'a'<'z'
//而这题要求忽略大小写,所以不能直接用字符串的比较。自定义了一个lt函数,就是less than的意思
//先把两个字符串全部转化为小写,再比较大小(字典序)
bool lt(string x,string y){
int i;
for(i=0;i<y.length();i++)
if(x[i]>='A'&&x[i]<='Z'){
x[i]='a'+(x[i]-'A');
}
for(i=0;i<y.length();i++){
if(y[i]>='A'&&y[i]<='Z')
y[i]='a'+(y[i]-'A');
}
return x<y;
}
//自定义的比较函数,先按b值升序排列(也就是"Dir"排在"File"前面)
//如果b值相同,再按a升序排列,用的是刚才定义的lt函数
bool comp(node x,node y){
if(x.b!=y.b){
return x.b<y.b;
}
return lt(x.a,y.a);
}
int main()
{
node arr[10001];
int size=0;
while(cin>>arr[size].a>>arr[size].b)
size++;
sort(arr,arr+size,comp);
for(int i=0;i<size;i++)
cout<<arr[i].a<<" "<<arr[i].b<<endl;
return 0;
}
下面通过这个例子,可以自己写一个跟标准库中相同功能的sort函数:(程序代码如下)
#include <stdio.h>
#define swap(x,y){double t=x;x=y;y=t;}//定义了一个宏函数,用来交换两变量值
void input(double a[], int n){
printf("请输入%d个小数:\n", n);
int i;
for(i=0; i<n; i++){
scanf("%lf",&a[i]); //也可以写成 a+i
}
}
int rule1(double lh, double rh){return (lh<rh);}//按从小到大顺序排列
int rule2(double lh, double rh){return (lh>rh);}//按从大到小顺序排列
//rule2对排序规则的约定:保持顺序就返回1,需要交换就返回0
void sort(double a[], int n, int (*p)(double, double) ){
int i, j;
for(i=0; i<n-1; i++){
for(j=i+1; j<n; j++){
if(p(a[i],a[j]) == 0){
swap(a[i],a[j]);
}
}
}
}
void show(double a[], int n){
int i;
for(i=0; i<n; i++){
printf("%g ", a[i]);
}
printf("\n");
}
int main(){
double a[5];
input(a,5);
sort(a,5,&rule1);
show(a,5);
return 0;
}