1. 程式人生 > 其它 >c語言min函式的使用方法_C語言qsort()函式的使用

c語言min函式的使用方法_C語言qsort()函式的使用

技術標籤:c語言min函式的使用方法

qsort()函式是 C 庫中實現的快速排序演算法,包含在 stdlib.h 標頭檔案中,其時間複雜度為 O(nlogn)。函式原型如下:

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

此函式需要四個引數。

第一個引數是需要排序的陣列的基地址,因為是 void * 型別,所以此函式可以給任何型別的陣列進行排序;

第二個引數是待排序的數量(size_t 是一種特別的資料型別,可以近似理解為 int 型);

第三個是單個數組元素的大小,即位元組數,例如 int 型就是 4 或者 sizeof(int) (sizeof 的返回值型別就是 sizeof),char 型就是 1 或者

sizeof(char)。因為為了適用於各種資料結構,第一個引數將指向陣列的指標強轉成了 void * 型別,也即此時函式並不知道將要進行排序的陣列記憶體儲的是什麼元素,因此我們需要顯式地告訴它單個元素所佔的長度;

第四個引數是一個指向函式的指標,其作用是規定排序的規則,即按照什麼樣的方式進行排序。

下面我們對一個整型陣列排序為例:

#include<stdio.h>
#include<stdlib.h>

//比較函式原型 
int mycmp(const void* p1, const void* p2);
 
int main() {
	
	int num[10] = {32, -4, 89, 232, 2, 12, -32, 0, -4, 89};
	
	qsort(num, 10, sizeof(int), mycmp);
	
	for(int i=0; i<10; i++)
		printf("%d ", num[i]);
	
	printf("n");
	return 0;
}

//比較函式 
int mycmp(const void* p1, const void* p2){
	const int * a = (const int *) p1;
	const int * b = (const int *) p2;
	
	int value = 0;
	
	if(*a < *b)
		value = -1;
	else if(*a == *b)
		value = 0;
	else value = 1;
	
	return value;
}

執行結果如下所示:

fde9a67bd2fb5b43b168eb6e6136d1f9.png

使用 qsort 最重要的是比較函式的編寫。

首先,qsort 函式的原型中已經對此元素的原型有了明確的規定:int (*compar)(const void *, const void *) ,需要傳入指向兩個元素的指標。

與上文增加第三個引數的原因相同,比較函式的引數指標是 void * 型別,這個引數同樣不知道元素實際的大小,因此我們需要進行型別的強轉,轉換成元素實際型別對應的指標,例如上文中為了給一個 int 型陣列排序:

const int * a = (const int *) p1;
const int * b = (const int *) p2;

然後,兩個元素之間的比較結果無非 > 、= 、< ,我們要給希望成立的結果返回 1,例如:如果希望從小到大排列,則 *a < *b 成立時返回 1;如果希望從大到小排列,則 *a > *b 返回 1,相應的 *a == *b 返回 0,*a < *b 返回 -1.

因此如果將上述程式的 1 和 -1 顛倒位置,結果就會變成降序排列:

3b0d020475d8e0dc928a50caa294db5a.png

因為可以任意編寫比較函式,當比較具有優先順序時我們也可以從容解決。

例如:

定義了這樣一個表示時間的結構體:

struct Time {
	int hour;
	int min;
	int sec;
};

如果對此型別的陣列元素進行升序排列,那麼比較函式應該為:

int mycomp(const void * p1, const void * p2){
	const Time * a = (const Time *) p1;
	const Time * b = (const Time *) p2;
	
	int value = 0;
	
	if(a->hour > b->hour)
		value = 1;
	else if(a->hour < b->hour)
		value = -1;
	
	else{
		if(a->min > b->min)
			value = 1;
		else if(a->min < b->min)
			value = -1;
		else{
			if(a->sec > b->sec)
				value = 1;
			else if(a->sec < b->sec)
				value = -1;
			else value = 0;
		}
	}
	
	return value;
}