国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【C語(yǔ)言】qsort()函數(shù)詳解:能給萬物排序的神奇函數(shù)

這篇具有很好參考價(jià)值的文章主要介紹了【C語(yǔ)言】qsort()函數(shù)詳解:能給萬物排序的神奇函數(shù)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

??個(gè)人主頁(yè):修修修也

??所屬專欄:C語(yǔ)言

??操作環(huán)境:Visual Studio 2022

?qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)


目錄

一.qsort()函數(shù)的基本信息及功能

二.常見的排序算法及冒泡排序

三.逐一解讀qsort()函數(shù)的參數(shù)及其原理

1.void* base

2.size_t num

3.size_t size

4.int (*compar)(const void*,const void*)

四.使用qsort()函數(shù)完成整形,結(jié)構(gòu)體的排序(演示)

1.使用qsort()函數(shù)完成對(duì)一維整形數(shù)組的排序:

2.使用qsort()函數(shù)完成對(duì)結(jié)構(gòu)體的排序:

1>.使用qsort()函數(shù)完成對(duì)結(jié)構(gòu)體按年齡排序

2>.使用qsort()函數(shù)完成對(duì)結(jié)構(gòu)體按姓名排序

?五.套用冒泡算法,改造并模擬實(shí)現(xiàn)qsort()函數(shù)

1.bubble_sort()函數(shù)定義及參數(shù)

2.bubble_sort()函數(shù)函數(shù)體:

3.bubble_sort()函數(shù)中的回調(diào)函數(shù)Swap():

六.使用bubble_sort()函數(shù)完成整形,結(jié)構(gòu)體的排序(演示)

1.使用bubble_sort()函數(shù)完成對(duì)一維整形數(shù)組的排序:

2.使用bubble_sort()函數(shù)完成對(duì)結(jié)構(gòu)體的排序:

1>.使用bubble_sort()函數(shù)完成對(duì)結(jié)構(gòu)體按年齡排序

?2>.使用bubble_sort()函數(shù)完成對(duì)結(jié)構(gòu)體按姓名排序


一.qsort()函數(shù)的基本信息及功能

我們?nèi)粘I钪薪?jīng)常能碰到需要給一組數(shù)據(jù)排序的情況,如將班上同學(xué)的身高從大到小排序,將淘寶上的商品價(jià)格從低到高排序,將班上的同學(xué)姓名按首字母順序排序......隨著科學(xué)技術(shù)的發(fā)展,現(xiàn)在這些工作完全可以交給excel一鍵完成,那么電腦是根據(jù)什么程序完成這些排序的?

接下來我們就來給大家介紹一下C語(yǔ)言庫(kù)函數(shù)可以“給萬物排序”qsort()函數(shù)

先來看一下qsort()函數(shù)(quick sort)在百度百科中的定義qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

因此,qsort()函數(shù)是一個(gè)C語(yǔ)言編譯器函數(shù)庫(kù)自帶的排序函數(shù),它可以對(duì)指定數(shù)組(包括字符串,二維數(shù)組,結(jié)構(gòu)體等)進(jìn)行排序。


二.常見的排序算法及冒泡排序

我們熟知的數(shù)組排序的算法有很多,如冒泡排序,選擇排序,直插排序,希爾排序,并歸排序,快速排序等,具體八大算法的實(shí)現(xiàn)可以移步這篇博客【數(shù)據(jù)結(jié)構(gòu)】八大排序算法

了解了這些種類繁多的排序算法后,我們希望能夠使用一種較為簡(jiǎn)單的排序算法來實(shí)現(xiàn)qsort函數(shù)的功能,來模擬實(shí)現(xiàn)同樣具有可以排序數(shù)組,字符串,結(jié)構(gòu)體功能的排序函數(shù)。如,我們可以使用冒泡排序的算法來實(shí)現(xiàn)具有排序字符串,二維數(shù)組,結(jié)構(gòu)體等功能bubble_sort()函數(shù)。

如果還有不太熟悉冒泡排序的朋友可以移步這篇博客【C語(yǔ)言】冒泡排序詳解,里面有關(guān)于冒泡算法完全0基礎(chǔ)的詳解,這里就不多贅述了,我們?cè)谶@里直接演示一下冒泡排序的用法

冒泡排序算法演示(以升序?yàn)槔?/p>

數(shù)組元素初始順序如下:

int arr[10] = { 3,1,5,9,7,6,4,8,0,2 };

冒泡排序(升序)運(yùn)行結(jié)果qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

?冒泡排序(升序)完整代碼如下:

//冒泡排序<升序>
#include<stdio.h>
void print(int arr[])
{
	int i = 0;
	for (i = 0; i <= 9; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}
 
void sort(int arr[],int sz)
{
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		int j = 0;
		for(j=0;j<sz-1-i;j++)
		{	
			if (arr[j] > arr[j + 1])
			{
				int emp =arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = emp;
			}
		}
	}
}
 
int main()
{
	int arr[10] = { 3,1,5,9,7,6,4,8,0,2 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	print(arr);
	sort(arr,sz);
	print(arr);
	return 0;
}

三.逐一解讀qsort()函數(shù)的參數(shù)及其原理

在搞清了我們的排序算法后,接下來為了進(jìn)一步模仿實(shí)現(xiàn)qsort()函數(shù),我們需要逐一解讀qsort()函數(shù)的參數(shù)及其作用,以便后續(xù)模仿實(shí)現(xiàn)它。

從cplusplus官網(wǎng)(cplusplus(C語(yǔ)言函數(shù)查詢網(wǎng)站))上我們可以看到qsort()函數(shù)有四個(gè)參數(shù)的,如圖:qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

?而cplusplus官網(wǎng)對(duì)這四個(gè)變量的解釋是:qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)


接下來我們一起來分析一下這四個(gè)參數(shù)及其作用

1.void* base

void* base

qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

即,qsort()函數(shù)需要的第一個(gè)參數(shù)是待排序數(shù)組的首元素地址,而void*的意思是它是一個(gè)無類型指針,而無類型的原因是我們希望它是一個(gè)可以排序很多種類數(shù)據(jù)的排序函數(shù),如果這里的指針類型固定,我們就只能對(duì)函數(shù)傳入固定類型的參數(shù)進(jìn)行排序了。

因此,要讓qsort()函數(shù)幫助我們排序,首先要告訴它這組數(shù)據(jù)的首地址在哪。


2.size_t num

size_t num

qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

這個(gè)參數(shù)代表待排數(shù)組的元素個(gè)數(shù)。且因?yàn)?span style="color:#fe2c24;">元素個(gè)數(shù)恒為非負(fù)數(shù),因此該參數(shù)的數(shù)據(jù)類型size_t(即無符號(hào)整形)。

計(jì)算數(shù)組元素個(gè)數(shù)常用的是sizeof,即數(shù)組元素個(gè)數(shù)=數(shù)組總長(zhǎng)度/數(shù)組首元素長(zhǎng)度,如:

size_t num=sizeof(arr)/sizeof(arr[0]);

因此,要讓qsort()函數(shù)幫助我們排序,我們還要告訴它這個(gè)數(shù)組一共有多少個(gè)元素


3.size_t size

size_t size

?該參數(shù)意為待排數(shù)組中每個(gè)元素的長(zhǎng)度。同樣因?yàn)?span style="color:#fe2c24;">元素長(zhǎng)度恒為非負(fù)數(shù),因此參數(shù)的數(shù)據(jù)類型是size_t(無符號(hào)整形)。

計(jì)算數(shù)組元素長(zhǎng)度常用sizeof,及數(shù)組每個(gè)元素長(zhǎng)度=數(shù)組首元素的長(zhǎng)度,如:

size_t size=sizeof(arr[0]);

因此,要讓qsort()函數(shù)幫助我們排序,我們還要告訴它這個(gè)數(shù)組中的每個(gè)元素的長(zhǎng)度(即首元素的長(zhǎng)度)。


4.int (*compar)(const void*,const void*)

 int (*compar)(const void*,const void*)

這個(gè)應(yīng)該算最難理解的部分了,不過我們一點(diǎn)一點(diǎn)來看,還是先畫個(gè)圖幫助大家理解吧:qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

?經(jīng)過我們的分析可知,該參數(shù)是一個(gè)函數(shù)指針,該指針指向的函數(shù)需要兩個(gè)無類型的指針作為參數(shù),同時(shí)該函數(shù)的返回值是一個(gè)int類型的整形

他的作用是將傳進(jìn)來的兩個(gè)參數(shù)進(jìn)行比較,如果參數(shù)p1<參數(shù)p2,則返回一個(gè)小于0的數(shù),如果參數(shù)p1=參數(shù)p2,則返回0;如果參數(shù)p1>p2,則返回一個(gè)大于0的數(shù)。

注意!compar()函數(shù)的作用僅僅是比較兩個(gè)參數(shù)的大小,并通過返回值的形式告訴qsort()函數(shù)比較的結(jié)果,在運(yùn)行期間是不能更改參數(shù)1或參數(shù)2的值的,所以為保險(xiǎn)起見,我們可以給兩個(gè)參數(shù)前加上const修飾,來使參數(shù)指向的數(shù)值無法改變。

小tips:const修飾的指針在*符號(hào)左邊即為固定指向的值不可改變,在*符號(hào)右邊則為固定指針指向的方向不可改變??梢院?jiǎn)記為:左定值,右定向。qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

compar()函數(shù)編寫樣例如下:qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

需要注意的是:這個(gè)指針指向的函數(shù)是由你自己編寫的,即qsort()函數(shù)會(huì)在其內(nèi)部調(diào)用你編寫的比較函數(shù),而這個(gè)比較函數(shù)如何比較qsort()函數(shù)傳遞的兩個(gè)參數(shù)完全由你自己定義的。

在qsort()函數(shù)調(diào)用完compar()函數(shù)后,會(huì)接收到compar()返回的一個(gè)有符號(hào)的整型數(shù)字,當(dāng)接收到comper()返回大于0的數(shù)字時(shí),qsort()函數(shù)就會(huì)將這兩個(gè)元素做交換。而如果接收到comper()函數(shù)返回小于等于0的數(shù)時(shí),qsort()函數(shù)不對(duì)其進(jìn)行交換。

因此,在compar()函數(shù)使用*p1-*p2的方式直接返回結(jié)果數(shù)字時(shí),qsort()排出的序默認(rèn)會(huì)是升序。而如果你希望qsort()函數(shù)排出一個(gè)降序數(shù)組時(shí),那么就需要調(diào)換一下*p1和*p2的減法關(guān)系,直接返回*p2-*p1的值即可。


下面列舉一些大家常用的compar()比較函數(shù)

1.對(duì)一維數(shù)組進(jìn)行排序

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

2.對(duì)二維數(shù)組進(jìn)行排序

int comper(const void*a,const void*b)
{
    return((int*)a)[0]-((int*)b)[0];
}

3.對(duì)字符串進(jìn)行排序

int comper(const void*p1,const void*p2)
{
    return strcmp((char*)p2,(char*)p1);
}

4.按結(jié)構(gòu)體中某個(gè)關(guān)鍵字排序(對(duì)結(jié)構(gòu)體一級(jí)排序):

structNode
{
    double data;
    int other;
}s[100];
 
int comper(constvoid*p1,constvoid*p2)
{
    return(*(Node*)p2).data>(*(Node*)p1).data?1:-1;
}

5.對(duì)結(jié)構(gòu)體中字符串進(jìn)行排序:

struct Node
{
    int data;
    char str[100];
}s[100];
//按照結(jié)構(gòu)體中字符串str的字典序排序
int comper(const void*p1,const void*p2)
{
    return strcmp((*(Node*)p1).str,(*(Node*)p2).str);
}

四.使用qsort()函數(shù)完成整形,結(jié)構(gòu)體的排序(演示)

了解了qsort()函數(shù)的參數(shù)及其原理后,我們來嘗試使用它完成一些排序任務(wù),以此來熟悉qsort()函數(shù)的使用方法。

1.使用qsort()函數(shù)完成對(duì)一維整形數(shù)組的排序:

要使用qsort()函數(shù),就要先準(zhǔn)備好需要的四個(gè)參數(shù),即數(shù)組的首地址,數(shù)組的長(zhǎng)度,數(shù)組每個(gè)元素的長(zhǎng)度,還有比較函數(shù)的地址(即函數(shù)名)。我們依次準(zhǔn)備好這四個(gè)參數(shù):
qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

?接下來就可以調(diào)用qsort()函數(shù)查看結(jié)果了:qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

?可以看到,qsort()函數(shù)成功幫我們將該組整形排列成了升序。該部分完整代碼如下

//使用qsort()函數(shù)排序一維數(shù)組
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>

int compar(const void* p1, const void* p2)
{
    return ((*(int*)p1) - (*(int*)p2));
}

int main()
{
	int arr[10] = { 3,1,5,9,7,6,4,8,0,2 };
	size_t num = sizeof(arr) / sizeof(arr[0]);
	size_t sz = sizeof(arr[0]);
	qsort(arr, num, sz, compar);
    int i=0;
	for (i = 0; i < num; i++)
		printf("%d ", arr[i]);
	return 0;
}

2.使用qsort()函數(shù)完成對(duì)結(jié)構(gòu)體的排序:

要使用qsort()函數(shù)排序結(jié)構(gòu)體,我們首先要創(chuàng)建一個(gè)結(jié)構(gòu)體變量,如下,我們先創(chuàng)建一個(gè)包含人名和年齡結(jié)構(gòu)體變量qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

?下面會(huì)以這個(gè)結(jié)構(gòu)體變量為例,分別實(shí)現(xiàn)使用qsort()函數(shù)完成對(duì)結(jié)構(gòu)體按年齡按姓名的排序。

1>.使用qsort()函數(shù)完成對(duì)結(jié)構(gòu)體按年齡排序

我們照例先準(zhǔn)備好它需要的四個(gè)參數(shù),即結(jié)構(gòu)體的首地址,結(jié)構(gòu)體的長(zhǎng)度,結(jié)構(gòu)體每個(gè)元素的長(zhǎng)度,還有比較函數(shù)的地址。我們依次準(zhǔn)備好這四個(gè)參數(shù):

qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

?接下來就可以調(diào)用qsort()函數(shù)查看結(jié)果了:qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

?可以看到,qsort()函數(shù)幫助我們將該結(jié)構(gòu)體成功按年齡從小到大重新排序了。該部分完整代碼如下:

//使用qsort()函數(shù)按年齡排序結(jié)構(gòu)體
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//創(chuàng)建結(jié)構(gòu)體
struct Stu
{
	char name[20];
	int age;
};
//compar_按年齡排序
int compar_Stu_age(const void* p1, const void* p2)
{
	return ((struct Stu*)p1)->age - ((struct Stu*)p2)->age;
}

int main()
{
	struct Stu s[3] = { {"zhangsan",20} ,{"lisi",30},{"wangmazi",25} };
	size_t num = sizeof(s) / sizeof(s[0]);
	size_t sz = sizeof(s[0]);

	qsort(s, num, sz, compar_Stu_age);
	for (int i = 0; i < 3; i++)
	{
		printf("%s,%d\n", s[i].name, s[i].age);
	}
	return 0;
}

2>.使用qsort()函數(shù)完成對(duì)結(jié)構(gòu)體按姓名排序

我們照例先準(zhǔn)備好它需要的四個(gè)參數(shù),即結(jié)構(gòu)體的首地址,結(jié)構(gòu)體的長(zhǎng)度,結(jié)構(gòu)體每個(gè)元素的長(zhǎng)度,還有比較函數(shù)的地址。我們依次準(zhǔn)備好這四個(gè)參數(shù):

qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)需要特別注意按姓名排序的排序函數(shù),因?yàn)?span style="color:#fe2c24;">按姓名排序本質(zhì)上是給字符串排序,所以我們借助strcmp()函數(shù)來比較兩個(gè)字符串的大小,并將比較的結(jié)果返回給qsort()函數(shù)。

有關(guān)strcmp()函數(shù)相關(guān)信息如下:qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

?接下來就可以調(diào)用qsort()函數(shù)查看結(jié)果了:qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

?可以看到,qsort()函數(shù)按照名字順序(字典序)幫助我們成功排好了結(jié)構(gòu)體的順序,該部分完整代碼如下

//使用qsort()函數(shù)按姓名排序結(jié)構(gòu)體
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//創(chuàng)建結(jié)構(gòu)體
struct Stu
{
	char name[20];
	int age;
};

//compar_按姓名排序
int compar_Stu_name(const void* p1, const void* p2)
{
	return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);
}

int main()
{
	struct Stu s[3] = { {"zhangsan",20} ,{"lisi",30},{"wangmazi",25} };
	size_t num = sizeof(s) / sizeof(s[0]);
	size_t sz = sizeof(s[0]);

	qsort(s, num, sz, compar_Stu_name);
    //打印結(jié)果
	for (int i = 0; i < 3; i++)
	{
		printf("%s,%d\n", s[i].name, s[i].age);
	}
	return 0;
}

?五.套用冒泡排序算法,改造并模擬實(shí)現(xiàn)qsort()函數(shù)

通過上面的例子,我們已經(jīng)能夠熟練使用并足夠了解qsort()函數(shù)了,接下來我們就可以嘗試套用冒泡算法來試試實(shí)現(xiàn)bubble_sort()函數(shù)了:

1.bubble_sort()函數(shù)定義及參數(shù)

函數(shù)參數(shù)沒什么好說的,因?yàn)橐M實(shí)現(xiàn)qsort()函數(shù),因此直接仿照qsort()函數(shù)的參數(shù)即可:

void bubble_sort(void*base, size_t num,size_t sz,int(*compar)(const void*,const void*))

2.bubble_sort()函數(shù)函數(shù)體

函數(shù)體內(nèi)部邏輯整體參考冒泡排序,只在一小部分地方有略微的改動(dòng)。首先因?yàn)槲覀冊(cè)谡麄€(gè)bubble_sort()函數(shù)中都不知道base傳進(jìn)的參數(shù)到底是什么類型的,因此索性不去糾結(jié)數(shù)據(jù)的類型,干脆將他們統(tǒng)一視為一個(gè)字節(jié)一個(gè)字節(jié)的空間來進(jìn)行比較及交換,因此傳入bubble_sort()函數(shù)的指針統(tǒng)一強(qiáng)制類型轉(zhuǎn)換成char*類型以便后續(xù)我們一個(gè)字節(jié)一個(gè)字節(jié)操作。該部分代碼及解析如下:

{
	size_t i = 0;
	for (i = 0; i < num - 1; i++)
	{
		size_t j = 0;
		for (j = 0; j < num - 1 - i; j++)
		{
			if (compar((char*)base+j*sz,(char*)base+(j+1)*sz) > 0)
        //因?yàn)闊o法確定base到底代表什么類型的指針,因此不如全部當(dāng)作字符(只占1字節(jié))指針來處理
			{
				//交換
				Swap((char*)base + j * sz, (char*)base + (j + 1) * sz, sz);
                //交換思路同樣是一個(gè)字節(jié)一個(gè)字節(jié)交換
			}
		}
	}
}

3.bubble_sort()函數(shù)中的回調(diào)函數(shù)Swap()

我們把原本冒泡排序中的交換步驟直接重新分裝成一個(gè)函數(shù),專門用來交換比較后需要交換的兩個(gè)元素,同樣因?yàn)?span style="color:#fe2c24;">我們并不知道該數(shù)據(jù)的類型,只知道該數(shù)據(jù)的大小sz,因此我們不如直接將兩個(gè)sz大小的字節(jié)內(nèi)容逐個(gè)一個(gè)字節(jié)一個(gè)字節(jié)逐一交換,這樣就能保證不論是什么類型的數(shù)據(jù),交換完都不會(huì)出現(xiàn)差錯(cuò)了。該部分代碼如下:

//交換函數(shù)
void Swap(char* buf1, char* buf2,int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		char tmp = *buf1;
		*buf1 = *buf2;
		*buf2 = tmp;
		buf1++;
		buf2++;
	}
}

六.使用bubble_sort()函數(shù)完成整形,結(jié)構(gòu)體的排序(演示)

完成了bubble_sort()函數(shù)的編寫,接下來我們嘗試使用它來代替前面的qsort()函數(shù)給數(shù)組及結(jié)構(gòu)體進(jìn)行排序:

1.使用bubble_sort()函數(shù)完成對(duì)一維整形數(shù)組的排序

我們像之前使用qsort()那樣準(zhǔn)備好bubble_sort()所需要的四個(gè)參數(shù)

qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

接下來就可以使用bubble_sort()函數(shù)查看結(jié)果了:qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

?可以看到,bubble_sort()函數(shù)按照整形大小幫我們排好了升序。該部分完整代碼如下:

//使用冒泡排序排列一維數(shù)組
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>

void Swap(char* buf1, char* buf2,int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		char tmp = *buf1;
		*buf1 = *buf2;
		*buf2 = tmp;
		buf1++;
		buf2++;
	}
}

void bubble_sort(void*base, size_t num,size_t sz,int(*compar)(const void*,const void*))
{
	size_t i = 0;
	for (i = 0; i < num - 1; i++)
	{
		size_t j = 0;
		for (j = 0; j < num - 1 - i; j++)
		{
			if (compar((char*)base+j*sz,(char*)base+(j+1)*sz) > 0)
			{
				Swap((char*)base + j * sz, (char*)base + (j + 1) * sz, sz);
			}
		}
	}
}

int compar(const void* p1, const void* p2)
{
	return ((*(int*)p1) - (*(int*)p2));
}

int main()
{
	int arr[10] = { 3,1,5,9,7,6,4,8,0,2 };
	size_t num = sizeof(arr) / sizeof(arr[0]);
	size_t sz = sizeof(arr[0]);

	bubble_sort(arr, num, sz, compar);
	
	int i = 0;
	for (i = 0; i < num; i++)
		printf("%d ", arr[i]);
	return 0;
}

2.使用bubble_sort()函數(shù)完成對(duì)結(jié)構(gòu)體的排序

要使用bubble_sort()函數(shù)排序結(jié)構(gòu)體,我們首先要?jiǎng)?chuàng)建一個(gè)結(jié)構(gòu)體變量,如下,我們先創(chuàng)建一個(gè)包含人名和年齡的結(jié)構(gòu)體變量

qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

?下面會(huì)以這個(gè)結(jié)構(gòu)體變量為例,分別實(shí)現(xiàn)使用bubble_sort()函數(shù)完成對(duì)結(jié)構(gòu)體按年齡按姓名的排序。

1>.使用bubble_sort()函數(shù)完成對(duì)結(jié)構(gòu)體按年齡排序

我們照例先準(zhǔn)備好它需要的四個(gè)參數(shù),即結(jié)構(gòu)體的首地址結(jié)構(gòu)體的長(zhǎng)度,結(jié)構(gòu)體每個(gè)元素的長(zhǎng)度,還有比較函數(shù)的地址。我們依次準(zhǔn)備好這四個(gè)參數(shù):

qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

接下來就可以調(diào)用bubble_sort()函數(shù)查看結(jié)果了:qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

?可以看到,bubble_sort()函數(shù)幫助我們將該結(jié)構(gòu)體成功按年齡從小到大重新排序了。該部分完整代碼如下

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>

//交換函數(shù)
void Swap(char* buf1, char* buf2, int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		char tmp = *buf1;
		*buf1 = *buf2;
		*buf2 = tmp;
		buf1++;
		buf2++;
	}
}

void bubble_sort(void* base, size_t num, size_t sz, int(*compar)(const void*, const void*))
{
	size_t i = 0;
	for (i = 0; i < num - 1; i++)
	{
		size_t j = 0;
		for (j = 0; j < num - 1 - i; j++)
		{
			if (compar((char*)base + j * sz, (char*)base + (j + 1) * sz) > 0)
			{
				Swap((char*)base + j * sz, (char*)base + (j + 1) * sz, sz);
			}
		}
	}
}

struct Stu
{
	char name[20];
	int age;
};

//compar_按年齡排序
int compar_Stu_age(const void* p1, const void* p2)
{
	return ((struct Stu*)p1)->age - ((struct Stu*)p2)->age;
}

int main()
{
	struct Stu s[3] = { {"zhangsan",20} ,{"lisi",30},{"wangmazi",25} };
	size_t num = sizeof(s) / sizeof(s[0]);
	size_t sz = sizeof(s[0]);

	bubble_sort(s, num, sz, compar_Stu_age);

	for (int i = 0; i < 3; i++)
	{
		printf("%s,%d\n", s[i].name, s[i].age);
	}
	return 0;
}

?2>.使用bubble_sort()函數(shù)完成對(duì)結(jié)構(gòu)體按姓名排序

我們照例先準(zhǔn)備好它需要的四個(gè)參數(shù),即結(jié)構(gòu)體的首地址,結(jié)構(gòu)體的長(zhǎng)度,結(jié)構(gòu)體每個(gè)元素的長(zhǎng)度,還有比較函數(shù)的地址(即函數(shù)名)。我們依次準(zhǔn)備好這四個(gè)參數(shù):

qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

?接下來就可以調(diào)用bubble_sort()函數(shù)查看結(jié)果了:qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)

可以看到,bubble_sort()函數(shù)按照名字順序(字典序)幫助我們成功排好了結(jié)構(gòu)體的順序,該部分完整代碼如下

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
//交換函數(shù)
void Swap(char* buf1, char* buf2, int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		char tmp = *buf1;
		*buf1 = *buf2;
		*buf2 = tmp;
		buf1++;
		buf2++;
	}
}

void bubble_sort(void* base, size_t num, size_t sz, int(*compar)(const void*, const void*))
{
	size_t i = 0;
	for (i = 0; i < num - 1; i++)
	{
		size_t j = 0;
		for (j = 0; j < num - 1 - i; j++)
		{
			if (compar((char*)base + j * sz, (char*)base + (j + 1) * sz) > 0)
			{
				Swap((char*)base + j * sz, (char*)base + (j + 1) * sz, sz);
			}
		}
	}
}

struct Stu
{
	char name[20];
	int age;
};

//compar_按姓名排序
int compar_Stu_name(const void* p1, const void* p2)
{
	return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);
}

int main()
{
	struct Stu s[3] = { {"zhangsan",20} ,{"lisi",30},{"wangmazi",25} };
	size_t num = sizeof(s) / sizeof(s[0]);
	size_t sz = sizeof(s[0]);

	bubble_sort(s, num, sz, compar_Stu_name);

	for (int i = 0; i < 3; i++)
	{
		printf("%s,%d\n", s[i].name, s[i].age);
	}
	return 0;
}

七.qsort()的核心:快速排序算法

快速排序的思想

快排算法的基本思想是:

  • 通過一趟排序?qū)⒋艛?shù)據(jù)分割成獨(dú)立的兩部分
  • 其中一部分?jǐn)?shù)據(jù)的關(guān)鍵字均比另一部分?jǐn)?shù)據(jù)的關(guān)鍵字小
  • 可分別對(duì)這兩部分?jǐn)?shù)據(jù)繼續(xù)進(jìn)行排序,以達(dá)到整個(gè)序列有序的目的.

具體的快速排序算法是如何實(shí)現(xiàn)的,我放在另一篇博客中了,里面不僅有三種實(shí)現(xiàn)快排算法的方式,并且包含了如何使用非遞歸方式實(shí)現(xiàn)快排算法,這里有于篇幅有限,就不對(duì)贅述了,感興趣的朋友可以移步這篇博客:

【數(shù)據(jù)結(jié)構(gòu)】八大排序之快速排序算法https://blog.csdn.net/weixin_72357342/article/details/135059337

?


總結(jié)

以上就是關(guān)于qsort()函數(shù)及其模擬實(shí)現(xiàn)bubble_sort()函數(shù)的全部?jī)?nèi)容,希望能對(duì)大家有所幫助或有所啟發(fā),歡迎各位大佬在評(píng)論區(qū)或私信與我交流.

有關(guān)更多排序相關(guān)知識(shí)可以移步:

【數(shù)據(jù)結(jié)構(gòu)】八大排序算法https://blog.csdn.net/weixin_72357342/article/details/135038495?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22135038495%22%2C%22source%22%3A%22weixin_72357342%22%7D&fromshare=blogdetail

學(xué)海漫浩浩,我亦苦作舟!關(guān)注我,大家一起學(xué)習(xí),一起進(jìn)步!

相關(guān)文章推薦

【數(shù)據(jù)結(jié)構(gòu)】八大排序之堆排序算法

【數(shù)據(jù)結(jié)構(gòu)】八大排序之簡(jiǎn)單選擇排序

【數(shù)據(jù)結(jié)構(gòu)】八大排序之直接插入排序算法

【數(shù)據(jù)結(jié)構(gòu)】八大排序之希爾排序算法

【C語(yǔ)言】判斷字符類型的三種方法

【C語(yǔ)言】rand()函數(shù)(如何生成指定范圍隨機(jī)數(shù))

【C語(yǔ)言】memset()函數(shù)

【C語(yǔ)言】strlen()函數(shù)

【C語(yǔ)言】memcpy()函數(shù)


qsort函數(shù),C語(yǔ)言,算法,數(shù)據(jù)結(jié)構(gòu),排序算法,c語(yǔ)言,學(xué)習(xí)文章來源地址http://www.zghlxwxcb.cn/news/detail-739208.html


到了這里,關(guān)于【C語(yǔ)言】qsort()函數(shù)詳解:能給萬物排序的神奇函數(shù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • C語(yǔ)言標(biāo)準(zhǔn)庫(kù)函數(shù)qsort( )——數(shù)據(jù)排序

    C語(yǔ)言標(biāo)準(zhǔn)庫(kù)函數(shù)qsort( )——數(shù)據(jù)排序

    ?? 大家好!我是保護(hù)小周?,本期為大家?guī)淼氖巧疃冉馄蔆語(yǔ)言標(biāo)準(zhǔn)庫(kù)函數(shù) qsort(), qsort()函數(shù)他可以對(duì) 任意類型 的數(shù)據(jù)排序, 博主會(huì)詳細(xì)解釋函數(shù)使用方法,以及使用快速排序的左右指針法模擬實(shí)現(xiàn)函數(shù)功能 , 這樣的排序確定不來學(xué)習(xí)一下嗎??? ? 目錄 一、qsort()函

    2024年02月03日
    瀏覽(29)
  • 排序之玩轉(zhuǎn)qsort函數(shù)——【C語(yǔ)言】

    排序之玩轉(zhuǎn)qsort函數(shù)——【C語(yǔ)言】

    說起排序,我們會(huì)想起許多算法,在之前的博客中我也寫到過,比如:冒泡排序法、快速排序法、選擇排序法等等。其實(shí)在C語(yǔ)言中一直有一個(gè)可以將數(shù)組中的內(nèi)容進(jìn)行排序的函數(shù)且功能完善內(nèi)容齊全的庫(kù)函數(shù)——qsort函數(shù)。今天就讓我們來探索一下吧! 目錄 回調(diào)函數(shù) 初始

    2024年02月13日
    瀏覽(49)
  • C語(yǔ)言題目 - 調(diào)用qsort函數(shù)對(duì)數(shù)組進(jìn)行排序

    如題 其實(shí)沒什么難的,只要嚴(yán)格按照 qsort 函數(shù)的參數(shù)來填充即可,這里要用到 函數(shù)指針 。 qsort 函數(shù)的原型如下: void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void *)); 參數(shù)說明: base :指向需要排序的數(shù)組的指針,數(shù)組中每個(gè)元素的大小應(yīng)為 size 字節(jié)。

    2024年02月11日
    瀏覽(21)
  • 【C語(yǔ)言】——指針六:冒泡排序與qsort函數(shù)的實(shí)現(xiàn)

    【C語(yǔ)言】——指針六:冒泡排序與qsort函數(shù)的實(shí)現(xiàn)

    1.1、冒泡排序的原理 ?? ??在實(shí)踐過程中,我們難免會(huì)碰到要給一組數(shù)據(jù)排序的情況。如果我們掌握一些排序的算法,效率就會(huì)高很多。排序的方法有方法有很多,如:希爾排序,快速排序,堆排序……,今天,我們講的排序方法就是—— 冒泡排序 ! ?? ??冒泡排序

    2024年04月16日
    瀏覽(25)
  • C語(yǔ)言庫(kù)函數(shù)— qsort () 詳解

    C語(yǔ)言庫(kù)函數(shù)— qsort () 詳解

    目錄 1. qsort()函數(shù)簡(jiǎn)介 1.1 函數(shù)原型 1.2 函數(shù)參數(shù)? 2. 比較函數(shù)簡(jiǎn)介 2. 1 比較函數(shù)參數(shù)? 2.2 比較函數(shù)使用? 3. qsort()函數(shù)使用? 3.1 整形數(shù)組排序 ?3.2 字符數(shù)組排序 3.3 浮點(diǎn)型數(shù)組排序(double類型為例) 3. 4 字符串?dāng)?shù)組排序? 3.5 結(jié)構(gòu)體? qsort()函數(shù)是C語(yǔ)言庫(kù)函數(shù)中的一種 排序

    2024年02月05日
    瀏覽(24)
  • C語(yǔ)言——qsort函數(shù)的使用(詳解)

    C語(yǔ)言——qsort函數(shù)的使用(詳解)

    qsort()函數(shù)(quick sort)是八大排序算法中的快速排序,能夠排序任意數(shù)據(jù)類型的數(shù)組其中包括整形,浮點(diǎn)型,字符串甚至還有自定義的結(jié)構(gòu)體類型。 點(diǎn)擊網(wǎng)站:https://cplusplus.com/reference/——再點(diǎn)擊查看老版本函數(shù)超鏈接口(查看函數(shù)的含義) 老版本 在搜索框輸入要查詢的

    2024年02月14日
    瀏覽(21)
  • 【進(jìn)階C語(yǔ)言】qsort庫(kù)函數(shù)(詳解)

    【進(jìn)階C語(yǔ)言】qsort庫(kù)函數(shù)(詳解)

    qsort是C語(yǔ)言庫(kù)函數(shù)里面的一種,包含于#include stdlib.h這個(gè)頭文件里面,使用快速排序的方法 qsort英語(yǔ)解析:Quick sort,翻譯就是快速排序,它的內(nèi)部實(shí)現(xiàn)是通過的快速排序算法來實(shí)現(xiàn)的。 功能:對(duì)傳入的任何數(shù)據(jù)進(jìn)行排序,使其變成有序數(shù)列。 qsort是可以排序任意類型的數(shù)據(jù)

    2024年02月02日
    瀏覽(23)
  • 冒泡排序模擬實(shí)現(xiàn)qsort()函數(shù)

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

    要模擬qsort()函數(shù),我們首先要知道qsort()函數(shù)的特點(diǎn): 使用快速排序的方法。 適用于任何數(shù)據(jù)類型的排序。 但由于部分學(xué)者還沒有學(xué)習(xí)快速排序算法,所以本篇博客采用冒泡排序來模擬功能類似于qsort()的函數(shù)bubble_sort。 C庫(kù)對(duì)qsort()函數(shù)解釋: 我們得到的關(guān)于qsort()函數(shù)參

    2024年02月16日
    瀏覽(28)
  • 用冒泡排序?qū)崿F(xiàn)快速排序(qsort函數(shù)),指針進(jìn)階實(shí)例

    用冒泡排序?qū)崿F(xiàn)快速排序(qsort函數(shù)),指針進(jìn)階實(shí)例

    目錄 ? 1、qsort函數(shù)是什么 2、冒泡排序?qū)崿F(xiàn)指針進(jìn)階 2.1 主函數(shù) 2.2 功能函數(shù)聲明?編輯 2.3 my_qsort函數(shù)介紹 2.4 Swap函數(shù) 總結(jié) ? ? ? ? ? qsort函數(shù)是c語(yǔ)言自帶的函數(shù),其功能是實(shí)現(xiàn)快速排序。我們來看一下他的參數(shù)和返回值: ? ? ? ? 以上就是qsort的參數(shù)和返回值,可以看到,

    2024年02月21日
    瀏覽(26)
  • 對(duì)任意類型數(shù)都可以排序的函數(shù):qsort函數(shù)

    對(duì)任意類型數(shù)都可以排序的函數(shù):qsort函數(shù)

    之前我們學(xué)習(xí)過冒泡排序: 可以看出這樣的排序方法只適用于整形類型的數(shù) 那么是否有一種排序可以滿足所有類型都適用的排序呢? qsort函數(shù)排序 應(yīng)用: 在這里需要補(bǔ)充一下void* 類型的指針 當(dāng)然qsort函數(shù)排序既然可以實(shí)現(xiàn)任意類型,那么我們換幾個(gè)類型試一下; 結(jié)構(gòu)體類

    2024年02月14日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包