c標準庫中qsort函式用法

pengfoo發表於2012-02-22
 

轉自網路!

qsort函式是ANSI C標準中提供的,其宣告在stdlib.h檔案中,是根據二分發寫的,其時間複雜度為n*log(n),其結構為:

void qsort(void *base,size_t nelem,size_t width,int (*Comp)(const void *,const void *));

其中:

*base 為要排序的陣列

nelem 為要排序的陣列的長度

width 為陣列元素的大小(一位元組為單位)

預設是從小到大排序的!

* Comp(const void *p1,const void *p2) 為判斷大小函式的指標,這個函式需要自己定義,如果p1>p2,函式返回-1a<b,函式返回1a==b函式返回0

排序方法有很多種:選擇排序,氣泡排序,歸併排序,快速排序等。
看名字都知道快速排序是目前公認的一種比較好的排序演算法(我沒聽說速度比這快的了,特殊場合例外),比選擇排序,氣泡排序都要快。這是因為他速度很快,所以系統也在庫裡實現這個演算法,便於我們的使用。
這就是qsort

qsort 要求提供一個比較函式,是為了做到通用性更好一點。比如你不僅僅的是要排序一個數字而已,可能你要用來排序幾個數字,比如有一個結構

struct num

{
int a;
int b;
};

然後我有一個num 型別的陣列, num dddd[100];
我想給 dddd這個陣列排序,那怎麼辦?我想讓 a +b 最大的num元素排在陣列的最前面,那又怎麼辦?

這都可以通過定義比較函式來做到的。
比較函式的作用就是給qsort指明元素的大小是怎麼比較的。
像這樣的比較函式 inline int MyCmp(const void* a, const void* b)

都是有兩個元素作為引數,返回一個int值,如果比較函式返回大於0qsort就認為 a>b , 如果比較函式返回等於0 qsort就認為a b 這兩個元素相等,返回小於零 qsort就認為 a<b

qsort 知道元素大小,就可以把大的放到前面去。

如果你的比較函式放回本來應該是1 的(a>b),你比較函式卻返回一個 -1 (小於零的)那麼qsort認為a<b 的,就把 b放到前面去,但實際上是a大於b的,所以就造成升降序的差別了。

七種qsort排序方法

<
本文中排序都是採用的從小到大排序>

一、對int型別陣列排序

int num[100];

Sample:

int cmp ( const void *a , const void *b )
{
return *(int *)a - *(int *)b; //
強制轉換型別
}

qsort(num,100,sizeof(num[0]),cmp);

二、對char型別陣列排序(同int型別)

char word[100];

Sample:

int cmp( const void *a , const void *b )
{
return *(char *)a - *(char *)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)


四、對結構體一級排序

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

七、計算幾何中求凸包的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;
}

PS:

其中的qsort函式包含在<stdlib.h>的標頭檔案裡,strcmp包含在<string.h>的標頭檔案裡

相關文章