1. 程式人生 > >C中的qsort函式和C++中的sort函式的理解與使用

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、拓展知識點

  1. 為啥子使用qsort函式要指定排序元素的大小?
    ans:這是個腦殘的問題,給個腦殘的答案吧。因為qsort需要根據元素的大小來進行排序。
  2. 所使用的比較函式接受的是 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、not_equal_to、greater、greater_equal、less、less_equal。對於這些比較物件,我們可以望文生義就知道它們的意思了。
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()是類屬函式,可以用於比較任何容器,任何元素,任何條件。

相關推薦

no