成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

怎么樣才能做到對多種數(shù)據(jù)類型排序?C語言快速排序——qsort函數(shù)及其模擬實現(xiàn)

alphahans / 1299人閱讀

摘要:我們以冒泡排序為例,模擬實現(xiàn)函數(shù)。交換每單位字節(jié)對于的二進制序列這樣,冒泡排序就能排序多種數(shù)據(jù)類型,模擬實現(xiàn)了函數(shù),當然也可以使用其他的排序方法模擬實現(xiàn)函數(shù)。

??前面的話??

大家好!對于排序有許多中方法,比如冒泡排序,選擇排序,希爾排序,插入排序,堆排序等等,但是怎樣能夠使用一個函數(shù)能夠對多個數(shù)據(jù)類型進行排序呢?無所不知的C語言開發(fā)者提供了一個qsort函數(shù),它能夠對多種數(shù)據(jù)類型進行排序,實現(xiàn)各種數(shù)據(jù)類型的快速排序,這篇文章介紹qsort函數(shù)的使用及其模擬qsort函數(shù)的實現(xiàn)(基于冒泡排序)。

?博客主頁:未見花聞的博客主頁
?歡迎關注?點贊?收藏??留言?
?本文由未見花聞原創(chuàng),CSDN首發(fā)!
?首發(fā)時間:?2021年9月7日?
??堅持和努力一定能換來詩與遠方!
?參考書籍:?《明解C語言》?《C primer plus》
?參考在線編程網(wǎng)站:?牛客網(wǎng)?力扣
?作者水平很有限,如果發(fā)現(xiàn)錯誤,一定要及時告知作者哦!感謝感謝!
博主的碼云gitee,平常博主寫的程序代碼都在里面。


??qsort庫函數(shù)

?函數(shù)聲明

void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *elem1, const void *elem2 ) );

?庫

?函數(shù)功能

實現(xiàn)多個數(shù)據(jù)類型的快速排序。

?qosort函數(shù)各參數(shù)介紹

  • 返回類型:void 無返回值
  • 參數(shù)base:void* 無類型指針,可以接受任何指針類型,但是不能進行解引用,不能進行運算。該參數(shù)用來接受需要排序數(shù)組的首地址。
  • 參數(shù)num:size_t類型,本質上為無符號整型類型,該參數(shù)接受數(shù)組中元素的數(shù)量。
  • 參數(shù)width:size_t類型,本質上無符號整型類型,該參數(shù)接受數(shù)組中元素的內存大小,單位為字節(jié)。
  • 參數(shù)compare:函數(shù)指針類型,指向的函數(shù)類型為返回值為int,擁有2個參數(shù)的函數(shù),其實這兩個參數(shù)類型都為const void指針。該函數(shù)用來比較兩個地址對應的元素的大小。該參數(shù)用來回調compare所指向的函數(shù),是實現(xiàn)多數(shù)據(jù)類型排序的核心。

?compare函數(shù)

qsort函數(shù)中,其中一個參數(shù)是函數(shù)指針,指向一個用來比較兩個元素大小的函數(shù),不妨記該函數(shù)的第一個參數(shù)為e1,第二個參數(shù)為e2,兩個參數(shù)均為只可讀無類型指針,該函數(shù)返回值類型為int,記為x

  • x>0,表示e1指向的元素大于e2指向的元素。
  • x=0,表示e1指向的元素等于e2指向的元素。
  • x<0,表示e1指向的元素小于e2指向的元素。

實現(xiàn)整型類型比較的compare函數(shù)
如果qsort需要實現(xiàn)實現(xiàn)升序:

//升序int compare(const void* a, const void* b){	return (*(int*)a - *(int*)b);}

那需要實現(xiàn)降序呢?
其實很簡單,將上面return (*(int*)a - *(int*)b);改為return (*(int*)b - *(int*)a);就可以了。
實現(xiàn)浮點數(shù)比較的compare函數(shù)

int compare_dou(const void* a, const void* b){	double com = (*(double*)a - *(double*)b);	//防止數(shù)據(jù)發(fā)生截斷造成排序結果錯誤	if (com > 0)		return 1;	else if (com < 0)		return -1;	else		return 0;}int compare_fla(const void* a, const void* b){	float com = (*(float*)a - *(float*)b);	//防止數(shù)據(jù)發(fā)生截斷造成排序結果錯誤	if (com > 0)		return 1;	else if (com < 0)		return -1;	else		return 0;}

實現(xiàn)字符類型和字符串比較的compare函數(shù)

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

實現(xiàn)結構體類型比較compare函數(shù)

//參考結構體struct stu{	char name[20];	int age;	double score;};
int compare_stu(const void* a, const void* b){	//如果是字符串	return strcmp(((struct stu*)a)->name, ((struct stu*)b)->name);	//如果整型	//return (((struct stu*)a)->age - ((struct stu*)b)->age);	//如果是浮點型	//float com = (*(float*)a - *(float*)b);	//防止數(shù)據(jù)發(fā)生截斷造成排序結果錯誤	//if (com > 0)	//	return 1;	/*else if (com < 0)		return -1;	else		return 0;*/}

?測試

測試主函數(shù)

#include #include #include int main (){//test;}

測試1:整數(shù)排序

void test1(){	int arr[] = { 2,8,6,12,3,86,1,42,66,22,98,88 };	sz_t number = sizeof(arr) / sizeof(arr[0]);	sz_t size = sizeof(int);	sz_t i = 0;	printf("數(shù)組排序前:/n");	for (i = 0; i < number; i++)	{		printf("%d ", arr[i]);	}	qsort(arr, number, size, compare);	printf("/n數(shù)組排序后:/n");	for (i = 0; i < number; i++)	{		printf("%d ", arr[i]);	}}
數(shù)組排序前:2 8 6 12 3 86 1 42 66 22 98 88數(shù)組排序后:1 2 3 6 8 12 22 42 66 86 88 98D:/gtee/C-learning-code-and-project/練習使用qsort/Debug/練習使用qsort.exe (進程 37064)已退出,代碼為 0。按任意鍵關閉此窗口. . .

測試2:雙精度浮點數(shù)排序

void test2(){	double arr[5] = { 3.5,8.9,9.2,4.8,2.1 };	sz_t number = sizeof(arr) / sizeof(arr[0]);	sz_t size = sizeof(double);	sz_t i = 0;	printf("數(shù)組排序前:/n");	for (i = 0; i < number; i++)	{		printf("%.2lf ", arr[i]);	}	qsort(arr, number, size, compare_dou);	printf("/n數(shù)組排序后:/n");	for (i = 0; i < number; i++)	{		printf("%.2lf ", arr[i]);	}}
數(shù)組排序前:3.50 8.90 9.20 4.80 2.10數(shù)組排序后:2.10 3.50 4.80 8.90 9.20D:/gtee/C-learning-code-and-project/練習使用qsort/Debug/練習使用qsort.exe (進程 9984)已退出,代碼為 0。按任意鍵關閉此窗口. . .

測試3:結構體中字符串排序測試

void test3(){	struct stu arr[3] = { {"zhangsan", 15}, {"lisi", 30},{"wangwu", 10} };	sz_t number = sizeof(arr) / sizeof(arr[0]);	sz_t size = sizeof(arr[0]);	sz_t i = 0;	printf("數(shù)組排序前:/n");	for (i = 0; i < number; i++)	{		printf("%s ", arr[i].name);	}	qsort(arr, number, size, compare_stu);	printf("/n數(shù)組排序后:/n");	for (i = 0; i < number; i++)	{		printf("%s ", arr[i].name);	}}
數(shù)組排序前:zhangsan lisi wangwu數(shù)組排序后:lisi wangwu zhangsanD:/gtee/C-learning-code-and-project/練習使用qsort/Debug/練習使用qsort.exe (進程 29572)已退出,代碼為 0。按任意鍵關閉此窗口. . .

??模擬實現(xiàn)qsort函數(shù)

經(jīng)過對qsort函數(shù)的了解,我們發(fā)現(xiàn)該函數(shù)能夠對多種數(shù)據(jù)類型進行排序取決于傳入的函數(shù)指針參數(shù)。我們以冒泡排序為例,模擬實現(xiàn)qsort函數(shù)。

?冒泡排序改裝思路

先來看看冒泡排序函數(shù)

#define _CRT_SECURE_NO_WARNINGS 1#include //冒泡排序(int) 從小到大void bubble_sort(int* arr, int size){	int i = 0;	for (i = 0; i < size - 1; i++)	{		int j = 0;		int flag = 1;//判斷數(shù)據(jù)是否發(fā)生交換,默認沒有發(fā)生交換		for (j = 0; j < size - 1 - i; j++)		{			if (arr[j] > arr[j + 1])			{				int tmp = arr[j];				arr[j] = arr[j + 1];				arr[j + 1] = tmp;				flag = 0;			}		}		if (flag)			break;	}}

如果需要對多種數(shù)據(jù)類型進行排序,對應上面的這個冒泡排序,它所接受的參數(shù)肯定是必須改的,因為要接受多種數(shù)據(jù)類型的指針,所以傳入的指針必須是無具體類型void。函數(shù)內部中循環(huán)排序的次數(shù)是沒有發(fā)生改變的,所以函數(shù)內部的兩層循環(huán)是不用發(fā)生改變的,但是由于傳進來的是void型指針,無法進行運算和解引用,所以判斷語句是需要進行改動的。

?冒泡排序模擬實現(xiàn)qsort函數(shù)

對與if語句中所對應條件,我們可以調用compare函數(shù),將數(shù)組的前一個元素與后一個元素比較,如果該函數(shù)返回值大于0,表示數(shù)組前面的元素比后面的元素大,如果進行升序排列,我們需要對這兩個元素進行交換。這個交換我們不妨封裝在一個swap函數(shù)里,由于不知道數(shù)據(jù)類型,所以swap函數(shù)的參數(shù)為兩個元素的無類型地址,交換的時候我們不妨強制轉換為char*類型,因為char類型大小為1字節(jié),根據(jù)需要交換元素的大小,我們一個一個地將每個單位字節(jié)的二進制序列交換,這樣就完成了交換。對于如何得到相鄰元素的首地址,同理我們先可以將傳入指針強制轉換為char*類型任何根據(jù)元素內存大小,計算的出每個元素的地址。比如數(shù)組元素內存大小為width,則相鄰兩元素地址可以表示為(char*)val + j * width, (char*)val + (j + 1) * width。
知道了冒泡排序哪個地方需要改裝,我們來試著動手實踐一下。

typedef unsigned int sz_t;
void bubble_qsort(void* val, sz_t size, sz_t width, int (*cmp)(const void* p1, const void* p2)){	sz_t i = 0;	for (i = 0; i < size - 1; i++)	{		sz_t j = 0;		sz_t flag = 1;		for (j = 0; j < size - 1 - i; j++)		{			if (cmp((char*)val + j * width, (char*)val + (j + 1) * width) > 0)			{				swap((char*)val + j * width, (char*)val + (j + 1) * width, width);				flag = 0;			}		}		if (flag)			break;	}}
void swap(char* buf1, char* buf2, sz_t width){	sz_t i = 0;	for (i = 0; i < width; i++)	{		char tmp = *(buf1 + i);		*(buf1 + i) = *(buf2 + i);		*(buf2 + i) = tmp;//交換每單位字節(jié)對于的二進制序列	}}

這樣,冒泡排序就能排序多種數(shù)據(jù)類型,模擬實現(xiàn)了qsort函數(shù),當然也可以使用其他的排序方法模擬實現(xiàn)qsort函數(shù)。

?測試

測試主函數(shù)

#include #include #include int main (){//test;}

測試1:整數(shù)排序

void test1(){	int arr[] = { 2,8,6,12,3,86,1,42,66,22,98,88 };	sz_t number = sizeof(arr) / sizeof(arr[0]);	sz_t size = sizeof(int);	sz_t i = 0;	printf("數(shù)組排序前:/n");	for (i = 0; i < number; i++)	{		printf("%d ", arr[i]);	}	bubble_qsort(arr, number, size, compare);	printf("/n數(shù)組排序后:/n");	for (i = 0; i < number; i++)	{		printf("%d ", arr[i]);	}}
數(shù)組排序前:2 8 6 12 3 86 1 42 66 22 98 88數(shù)組排序后:1 2 3 6 8 12 22 42 66 86 88 98D:/gtee/C-learning-code-and-project/練習使用qsort/Debug/練習使用qsort.exe (進程 10620)已退出,代碼為 0。按任意鍵關閉此窗口. . .

測試2:雙精度浮點數(shù)排序

void test2(){	double arr[5] = { 3.5,8.9,9.2,4.8,2.1 };	sz_t number = sizeof(arr) / sizeof(arr[0]);	sz_t size = sizeof(double);	sz_t i = 0;	printf("數(shù)組排序前:/n");	for (i = 0; i < number; i++)	{		printf("%.2lf ", arr[i]);	}	bubble_qsort(arr, number, size, compare_dou);	printf("/n數(shù)組排序后:/n");	for (i = 0; i < number; i++)	{		printf("%.2lf ", arr[i]);	}}
數(shù)組排序前:3.50 8.90 9.20 4.80 2.10數(shù)組排序后:2.10 3.50 4.80 8.90 9.20D:/gtee/C-learning-code-and-project/練習使用qsort/Debug/練習使用qsort.exe (進程 34200)已退出,代碼為 0。按任意鍵關閉此窗口. . .

測試3:結構體中字符串排序測試

void test3(){	struct stu arr[3] = { {"zhangsan", 15}, {"lisi", 30},{"wangwu", 10} };	sz_t number = sizeof(arr) / sizeof(arr[0]);	sz_t size = sizeof(arr[0]
                 
               
              

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://m.hztianpu.com/yun/119676.html

相關文章

  • C語言進階:指針進階續(xù)

    摘要:故使用無具體類型,又稱通用類型,即可以接收任意類型的指針,但是無法進行指針運算解引用,整數(shù)等。求指針所占字節(jié)而不是解引用訪問權限大小。數(shù)組就是整個數(shù)組的大小,數(shù)組元素則是數(shù)組元素的大小,指針大小都為。 ...

    ingood 評論0 收藏0
  • C語言-qsort函數(shù)詳解

    摘要:目錄一函數(shù)是什么二使用排序以升序為例關于型指針整形數(shù)組排序字符數(shù)組排序字符指針數(shù)組排序結構體數(shù)組排序浮點型數(shù)組排序三使用冒泡排序思想模擬實現(xiàn)函數(shù)什么是冒泡排序冒泡排序代碼使用冒泡排序思想模 目錄 一.qsort函數(shù)是什么 ?二.使用qsort排序-以升序為例 ? ? ??關于void*型指針...

    Airmusic 評論0 收藏0
  • C語言qsort()函數(shù)的使用(詳解)

    摘要:參數(shù)含義上圖是函數(shù)各個參數(shù)的含義,讓我們一個個來看。使用方式頭文件要使用函數(shù)我們首先需要引用一個頭文件的實現(xiàn)函數(shù)給函數(shù)規(guī)定了特定的參數(shù)。因此我們設計函數(shù)時要嚴格遵守其參數(shù)設定。 目錄 1.參數(shù)含義 1.首元素地址base 2.元素個數(shù)num 3.元素大小size 4.自定義比較函數(shù)compa...

    wangym 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<