zoukankan      html  css  js  c++  java
  • C中的qsort函数和C++中的sort函数的理解与使用

    一、qsort()函数

    原型:_CRTIMP void __cdecl qsort (void*, size_t, size_t,int (*)(const void*, const void*));

    参数解释:1、待排序数组首地址;2、数组中待排序元素数量;3、各元素的占用空间的大小;4、指向函数的指针,用于确定排序的顺序。

    说明:qsort函数是ANSI C标准中提供的,其声明在stdlib.h文件中,是根据二分法写的,时间复杂度为O(n*logn)。

    qsort要求提供比较函数用来确定排序的顺序(升序、降序),比较函数使得qsort通用性更好,可以对数组、字符串、结构体数进行排序。如int cmp(const void *a, const void *b)中有两个元素作为参数(参数的格式不能变的。)返回一个int值,如果比较函数返回大于0,qsort就认为a > b,返回小于0,qsort就认为a < b。

    1、qsort中几种常见的cmp函数

    1.1、对int类型数组排序

    int num[100];
    int cmp(const void *a, const void *b)
    {
        return *(int *)a - *(int *)b;
    }
    
    qsort(num, 100, sizeof(int), cmp);

    1.2、对char类型数组排序

    char num[100];
    int cmp(const void *a, const void *b)
    {
        return *(char *)a - *(char *)b;
    }
    
    qsort(num, 100, sizeof(char), cmp);

    1.3、对double类型数组排序

    double num[100];
    int cmp(const void *a, const void *b)
    {
        return *(double *)a > *(double *)b;
    }
    
    qsort(num, 100, sizeof(double), cmp);

    1.4、对结构体数组一级排序

    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(In),cmp); 

    1.5、对结构体数组二级排序

    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(In),cmp);       

    1.6、对字符串进行排序

    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(In),cmp); 

    1.7、计算几何中求凸包的cmp

    int cmp(const void *a,const void *b) //重点cmp函数,把除了1点外的所有点,旋转角度排序 
    {
        struct point *c=(point *)a;
        struct point *d=(point *)b;
        if( calc(*c,*d,p[1]) < 0) 
        return 1; else if( !calc(*c,*d,p[1]) && dis(c->x,c->y,p[1].x,p[1].y) < dis(d->x,d->y,p[1].x,p[1].y)) //如果在一条直线上,则把远的放在前面   return 1; else
        return -1; }

    2、拓展知识点

    one、为啥子使用qsort函数要指定排序元素的大小?

    ans:这是个脑残的问题,给个脑残的答案吧。因为qsort需要根据元素的大小来进行排序。

    two、 所使用的比较函式接受的是 const void* 类型?

    ans:因为考虑到qsort的通用性,这样可以对数组,结构体数组等类型进行排序了。

    二、sort()函数

    函数名功能描述
    sort 对给定区间所有元素进行排序
    stable_sort 对给定区间所有元素进行稳定排序
    partial_sort 对给定区间所有元素部分排序
    partial_sort_copy 对给定区间复制并排序
    nth_element 找出给定区间的某个位置对应的元素
    is_sorted 判断一个区间是否已经排好序
    partition 使得符合某个条件的元素放在前面
    stable_partition 相对稳定的使得符合某个条件的元素放在前面

    要使用上述函数必须加上头文件algorithm。

    1、sort(begin,end)

    小例子

    #include<algorithm>
    
    int _tmain(int argc, _TCHAR* argv[])
    {
         int a[20]={2,4,1,23,5,76,0,43,24,65},i;
         for(i=0;i<20;i++)
              cout<<a[i]<<endl;
         sort(a,a+20);
         for(i=0;i<20;i++)
             cout<<a[i]<<endl;
         return 0;
    }    

    输出结果是把数组a按升序排序,也就是sort函数的排序默认是升序的。

    如何使用sort函数降序排序,ok!就像qsort中一样,我们需要自定义一个比较函数cmp(返回值为bool类型)。

    2、重载的sort函数-带比较函数的sort(begin,end,cmp)

    定义比较函数的方法

    2.1、常用方法

    下面的比较函数可以实现降序排序:

    bool cmp(int a,int b)
    {
        return a>b;      
    }

    2.2、使用枚举类型enum来定义升序或者降序排序。

    //ASC升序,DESC降序
    enum Cmp{ASC,DESC};

    2.3 定义一个比较类,来描述排序的顺序。

    class compare
    {
          private:
                Cmp comp;
          public:
                compare(Cmp c):comp(c) {};
          bool operator () (int num1,int num2) 
             {
                switch(comp)
                  {
                     case ASC:
                            return num1<num2;
                     case DESC:
                            return num1>num2;
                  }
              }
    };

    测试一下:

    int main()
    {
         int a[20]={2,4,1,23,5,76,0,43,24,65},i;
         for(i=0;i<20;i++)
             cout<<a[i]<<endl;
         sort(a,a+20,compare(DESC));
         for(i=0;i<20;i++)
             cout<<a[i]<<endl;
         return 0;
    }

    了解一下即可,因为比较麻烦,根据实际情况使用。

    2.4、使用functional头文件中的比较对象。

    functional提供了一堆基于模板的比较函数对象。equal_to<Type>、not_equal_to<Type>、greater<Type>、greater_equal<Type>、less<Type>、less_equal<Type>。对于这些比较对象,我们可以望文生义就知道它们的意思了。

    for example:

    sort(begin,end,less<data-type>();//升序
    
    sort(begin,end,greater<data-type>();//降序

    接着上面的例子,使用一下比较对象

    int _tmain(int argc, _TCHAR* argv[])
    {
          int a[20]={2,4,1,23,5,76,0,43,24,65},i;
          for(i=0;i<20;i++)
              cout<<a[i]<<endl;
          sort(a,a+20,greater<int>());
          for(i=0;i<20;i++)
              cout<<a[i]<<endl;
          return 0;
    }

    三、qsort函数和sort函数的PK。

    1、cmp函数不同

    返回值类型不同,qsort函数的cmp返回值类型为int,sort函数的cmp返回值为bool。

    参数不同,sort函数的cmp可以直接是参与比较的引用类型,而qsort是严格的空指针类型。

    比较表达式不同,qsort中的cmp使用的是“-”号,而sort中的cmp使用的是“>”。

    2、性能的区别

    sort函数是c++中标准模板库的的函数,在qsort()上已经进行了优化,根据情况的不同可以采用不同的算法,所以较快。在同样的元素较多和同样的比较条件下,sort()的执行速度都比qsort()要快。另外,sort()是类属函数,可以用于比较任何容器,任何元素,任何条件。

  • 相关阅读:
    JavaEE——SpringMVC(11)--拦截器
    JavaEE——SpringMVC(10)--文件上传 CommonsMultipartResovler
    codeforces 460A Vasya and Socks 解题报告
    hdu 1541 Stars 解题报告
    hdu 1166 敌兵布阵 解题报告
    poj 2771 Guardian of Decency 解题报告
    hdu 1514 Free Candies 解题报告
    poj 3020 Antenna Placement 解题报告
    BestCoder5 1001 Poor Hanamichi(hdu 4956) 解题报告
    poj 1325 Machine Schedule 解题报告
  • 原文地址:https://www.cnblogs.com/tgycoder/p/5016846.html
Copyright © 2011-2022 走看看