排序函数

排序在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项取样,更完全的三路划分算法,更细致的对不同数组大小采用不同方法排序。


 

 

posted @ 2014-04-10 16:05  money_lady  阅读(775)  评论(0编辑  收藏  举报