• qsort、bsearch


    qsort函数声明如下:

    void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));

    参数说明如下:
    base: 要排序的数组
    nmemb: 数组中的元素数目
    size: 每个数组元素占用内存空间,可使用sizeof获得
    compar: 比较两个数组元素的比较函数。本比较函数的第一个参数值小于、等于、大于第二参数值时,本比较函数的返回值应分别小于、等于、大于零。

    也就说你要实现一个这样的函数:
    int cmp(const void *a, const void *b)
    如果a > b,返回>0
    如果a == b, 返回0
    如果a < b,返回<0
    这里的a和b的关系仅仅是逻辑上的,并不是值比较,所以排序的可以不仅仅是数字,还可以是字符。

    注意:这个函数只能将base中的元素升序排列(太让我失望了)!!!

    bsearch函数声明如下:

    void *bsearch(const void *key, const void *base, size_t *nelem,
    size_t width, int(*fcmp)(const void *, const *));

    参数的意思和qsort的差不多,区别在于:
    1. qsort用来排序,bsearch用二分法来查找元素
    2. bsearch中的base必须是升序排列的数组!!!
    3. 如果数组里有重复的答案,则bsearch会返回其中一个的地址 (具体返回哪一个不确定)
    4. bsearch有五个自变量,第一个是要找的东西,剩下的跟qsort一模一样
    5. bsearch如果没找到所求则回传NULL ,否则回传该元素被找到的地址(void *)

    c函数qsort()和bsearch()的用法
    使用qsort()排序 并 用 bsearch()搜索是一个比较常用的组合,使用方便快捷。
    qsort 的函数原型是void __cdecl qsort ( void *base, size_t num, size_t width, int (__cdecl *comp)(const void *, const void* ) )

    其中base是排序的一个集合数组,num是这个数组元素的个数,width是一个元素的大小,comp是一个比较函数。

    比如:对一个长为1000的数组进行排序时,int a[1000]; 那么base应为a,num应为 1000,width应为 sizeof(int),comp函数随自己的命名。

    qsort(a,1000,sizeof(int ),comp);

    其中comp函数应写为:

    int comp(const void *a,const void *b)
    {
    return *(int *)a-*(int *)b;
    }

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

    是对一个二维数组的进行排序:

    int a[1000][2]; 其中按照a[i][0]的大小进行一个整体的排序,其中a[i][1]必须和a[i][0]一起移动交换。

    qsort(a,1000,sizeof(int)*2,comp);

    int comp(const void *a,const void *b)
    {
    return ((int *)a)[0]-((int *)b)[0];
    }

    对字符串进行一个排序:

    char a[1000][20];

    qsort(a,1000,sizeof(char)*20,comp);

    int comp(const void *a,const void *b
    {
    return strcmp((char *)a,(char *)b);
    }

    对一个结构体进行排序:

    typedef struct str
    {
    char str1[11];
    char str2[11];
    }str,*stri;
    str strin[100001]={0};

    int compare(const void *a,const void *b)
    {
    return strcmp( ((str*)a)->str2 , ((str*)b)->str2 );
    }

    qsort(strin,total,sizeof(str),compare);

    而关于bsearch() ,他和qsort的用法基本一样,只是他的返回值是一个指向找到的单位元素的一个指针,另外他多了一个参数,是一个指向查找元素的一个指针。

    比如:从上面例子中的结构体数组中查找一个字符串:

    str *locate;
    char buffer[30]="abc";
    locate=(str*)bsearch(buffer,strin,total,sizeof(str),com);

    int com(const void *a,const void *b)
    {
    return strcmp( (char*)a, ((str*)b)->str2 );
    }

    可以大致比较两个函数的类似和差别。

    例程: POJ 2503 Babelfish

    #i nclude <stdio.h>
    #i nclude <string.h>
    #i nclude <stdlib.h>
    struct dict
    {
    char english[11];
    char foreign[11];
    }a[100001];
    int mycmp(const void * aa, const void * b)
    {
    return strcmp(((dict*)aa)->foreign, ((dict*)b)->foreign);
    }
    int cmp(const void* aa, const void* b)
    {
    return strcmp((char*) aa, ((dict*)b)->foreign);
    }
    int main()
    {
    char line[30], query[11];
    int i=0,j,k;
    while(gets(line))
    {
    if(!strcmp(line,"")) break;
    k = strlen(line);
    for(j=0; j<k; j++)
    if(line[j]==' ')
    {
    line[j]='';
    break;
    }
    strcpy(a[++i].english, line);
    strcpy(a[i].foreign, line+j+1);
    }
    qsort(a+1, i, sizeof(dict), mycmp);

    while(scanf("%s", query)!=EOF)
    {
    dict* f = (dict *) bsearch(query,a+1, i, sizeof(dict), cmp); if(f)
    printf("%s ",f->english);
    else
    printf("eh ");
    }
    return 0;
    }

    注意
    qsort 和bsearch的cmp函数不同的
    qsort 比较的时dict 数组的两个成员
    bsearch比较的时key 和dict中成员

    补:

    对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);  
    四、对结构体一级排序  
    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);  
    作者:BuildNewApp
    出处:http://syxchina.cnblogs.comBuildNewApp.com
    本文版权归作者、博客园和百度空间共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则作者会诅咒你的。
    如果您阅读了我的文章并觉得有价值请点击此处,谢谢您的肯定1。
  • 相关阅读:
    演示使用Metasploit入侵Windows
    Metasploit的基本使用
    安装使用lynis扫描Linux的安全漏洞
    使用Metasploit收集邮箱信息
    Kali Linux:使用nmap扫描主机
    Kali Linux安装SSH Server
    【转】PHP 无限级分类(递归)
    【转】Mysql only_full_group_by以及其他关于sql_mode原因报错详细解决方案
    ERROR 1366 (HY000): Incorrect string value: 'xADxE5x9BxBDxE9x82...' fo的解决方法
    深入理解HTTP协议
  • 原文地址:https://www.cnblogs.com/syxchina/p/2197377.html
Copyright © 2020-2023  润新知