国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

alphahans / 1236人閱讀

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

??前面的話??

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

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


??qsort庫(kù)函數(shù)

?函數(shù)聲明

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

?庫(kù)

?函數(shù)功能

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

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

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

?compare函數(shù)

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

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

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

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

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

int compare_dou(const void* a, const void* b){	double com = (*(double*)a - *(double*)b);	//防止數(shù)據(jù)發(fā)生截?cái)嘣斐膳判蚪Y(jié)果錯(cuò)誤	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ā)生截?cái)嘣斐膳判蚪Y(jié)果錯(cuò)誤	if (com > 0)		return 1;	else if (com < 0)		return -1;	else		return 0;}

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

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

實(shí)現(xiàn)結(jié)構(gòu)體類型比較compare函數(shù)

//參考結(jié)構(gòu)體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);	//如果是浮點(diǎn)型	//float com = (*(float*)a - *(float*)b);	//防止數(shù)據(jù)發(fā)生截?cái)嘣斐膳判蚪Y(jié)果錯(cuò)誤	//if (com > 0)	//	return 1;	/*else if (com < 0)		return -1;	else		return 0;*/}

?測(cè)試

測(cè)試主函數(shù)

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

測(cè)試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/練習(xí)使用qsort/Debug/練習(xí)使用qsort.exe (進(jìn)程 37064)已退出,代碼為 0。按任意鍵關(guān)閉此窗口. . .

測(cè)試2:雙精度浮點(diǎn)數(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/練習(xí)使用qsort/Debug/練習(xí)使用qsort.exe (進(jìn)程 9984)已退出,代碼為 0。按任意鍵關(guān)閉此窗口. . .

測(cè)試3:結(jié)構(gòu)體中字符串排序測(cè)試

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/練習(xí)使用qsort/Debug/練習(xí)使用qsort.exe (進(jìn)程 29572)已退出,代碼為 0。按任意鍵關(guān)閉此窗口. . .

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

經(jīng)過(guò)對(duì)qsort函數(shù)的了解,我們發(fā)現(xiàn)該函數(shù)能夠?qū)Χ喾N數(shù)據(jù)類型進(jìn)行排序取決于傳入的函數(shù)指針參數(shù)。我們以冒泡排序?yàn)槔M實(shí)現(xiàn)qsort函數(shù)。

?冒泡排序改裝思路

先來(lái)看看冒泡排序函數(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ā)生交換,默認(rèn)沒(méi)有發(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;	}}

如果需要對(duì)多種數(shù)據(jù)類型進(jìn)行排序,對(duì)應(yīng)上面的這個(gè)冒泡排序,它所接受的參數(shù)肯定是必須改的,因?yàn)橐邮芏喾N數(shù)據(jù)類型的指針,所以傳入的指針必須是無(wú)具體類型void。函數(shù)內(nèi)部中循環(huán)排序的次數(shù)是沒(méi)有發(fā)生改變的,所以函數(shù)內(nèi)部的兩層循環(huán)是不用發(fā)生改變的,但是由于傳進(jìn)來(lái)的是void型指針,無(wú)法進(jìn)行運(yùn)算和解引用,所以判斷語(yǔ)句是需要進(jìn)行改動(dòng)的。

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

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

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é)對(duì)于的二進(jìn)制序列	}}

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

?測(cè)試

測(cè)試主函數(shù)

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

測(cè)試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/練習(xí)使用qsort/Debug/練習(xí)使用qsort.exe (進(jìn)程 10620)已退出,代碼為 0。按任意鍵關(guān)閉此窗口. . .

測(cè)試2:雙精度浮點(diǎn)數(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/練習(xí)使用qsort/Debug/練習(xí)使用qsort.exe (進(jìn)程 34200)已退出,代碼為 0。按任意鍵關(guān)閉此窗口. . .

測(cè)試3:結(jié)構(gòu)體中字符串排序測(cè)試

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]
                 
               
              

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/119676.html

相關(guān)文章

  • C語(yǔ)言進(jìn)階:指針進(jìn)階續(xù)

    摘要:故使用無(wú)具體類型,又稱通用類型,即可以接收任意類型的指針,但是無(wú)法進(jìn)行指針運(yùn)算解引用,整數(shù)等。求指針?biāo)甲止?jié)而不是解引用訪問(wèn)權(quán)限大小。數(shù)組就是整個(gè)數(shù)組的大小,數(shù)組元素則是數(shù)組元素的大小,指針大小都為。 ...

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

    摘要:目錄一函數(shù)是什么二使用排序以升序?yàn)槔P(guān)于型指針整形數(shù)組排序字符數(shù)組排序字符指針數(shù)組排序結(jié)構(gòu)體數(shù)組排序浮點(diǎn)型數(shù)組排序三使用冒泡排序思想模擬實(shí)現(xiàn)函數(shù)什么是冒泡排序冒泡排序代碼使用冒泡排序思想模 目錄 一.qsort函數(shù)是什么 ?二.使用qsort排序-以升序?yàn)槔?? ? ??關(guān)于void*型指針...

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

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

    wangym 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<