日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

C語(yǔ)言中qsort函數(shù)用法及用冒泡排序?qū)崿F(xiàn)_C 語(yǔ)言

作者:蝸牛牛啊 ? 更新時(shí)間: 2022-12-02 編程語(yǔ)言

一、qsort函數(shù)簡(jiǎn)介

qsort函數(shù)是由C語(yǔ)言提供的標(biāo)準(zhǔn)庫(kù)函數(shù), 它的實(shí)現(xiàn)思想是快速排序,qosrt函數(shù)的頭文件是stdlib.h。

qsort函數(shù)可以排序任意類(lèi)型的數(shù)組。它的返回類(lèi)型是void,參數(shù)是(void* base,size_t num,size_t size,int(*compar)(const void* e1,const void* e2))

接下來(lái)對(duì)它的參數(shù)進(jìn)行分析:

參數(shù)void* base中base是void*類(lèi)型的指針,base指向待排序數(shù)組的第一個(gè)元素的地址,也就是指向數(shù)組的起始位置。

參數(shù)size_t num中size_t表示的是無(wú)符號(hào)整型,num表示的是待排序數(shù)組中總的元素個(gè)數(shù)。

參數(shù)size_t size中size表示的是待排序數(shù)組中每個(gè)元素占幾個(gè)字節(jié)。

參數(shù)int (*compar)(const void* e1, const void* e2)是函數(shù)指針,int表示指向函數(shù)的返回類(lèi)型是int類(lèi)型,compar表示的是函數(shù)指針變量,指向函數(shù)的地址,被指向的函數(shù)用于比較兩個(gè)元素的大小。

在參數(shù)int (*compar)(const void* e1, const void* e2)中,函數(shù)指針變量compar指向的函數(shù)返回類(lèi)型是int,返回值的大小可以分為三種情況:

返回值 條件
>0 e1>e2
<0 e1<e2
=0 e1=e2

二、qsort函數(shù)的使用

1.整型數(shù)組排序

#include <stdio.h>
#include <stdlib.h>
int cmp_int(const void* e1, const void* e2)
{
    return *((int*)e1) - *((int*)e2);//默認(rèn)是升序,將return中e1和e2的位置交換可以使其降序
    //無(wú)法對(duì)void*類(lèi)型的指針進(jìn)行具體操作,因此要將其強(qiáng)制類(lèi)型轉(zhuǎn)換為int*,使其能夠在解引用時(shí)訪(fǎng)問(wèn)到4個(gè)字節(jié)
}
int main()
{
    int i = 0;
    int arr[] = { 7,8,9,4,5,6,1,2,3,10 };
    int sz = sizeof(arr) / sizeof(arr[0]);//計(jì)算整型數(shù)組中有多少個(gè)元素
    qsort(arr, sz, sizeof(int), cmp_int);//sizeof(int)是用來(lái)計(jì)算int類(lèi)型的數(shù)據(jù)所占字節(jié)數(shù)
    for (i = 0; i < sz; i++)
    {
        printf("%d ", arr[i]);//輸出為1 2 3 4 5 6 7 8 9 10
    }
    return 0;
}

注意:當(dāng)函數(shù)的形參為void*類(lèi)型,要對(duì)其進(jìn)行具體操作時(shí),應(yīng)該將其強(qiáng)制類(lèi)型轉(zhuǎn)換為所需的指針類(lèi)型

2.字符串排序

#include <stdio.h>
#include <stdlib.h>
int cmp_char(const void* e1, const void* e2)//字符串排序
{
    return strcmp((char*)e1, (char*)e2);//比較字符大小用strcmp
}
int main()
{
    char arr[] = "badecf";
    int i = 0;
    //int sz = sizeof(arr) / sizeof(arr[0]);//sizeof求字符串長(zhǎng)度會(huì)將\0算進(jìn)去,也就是實(shí)際計(jì)算出來(lái)的會(huì)比數(shù)組中的多1。
    int sz = strlen(arr);//strlen是用來(lái)計(jì)算字符串長(zhǎng)度的,且只能用來(lái)計(jì)算字符串的長(zhǎng)度。
    qsort(arr,sz , sizeof(char), cmp_char);
    printf("%s\n", arr);//abcdef
    return 0;
}

3.字符串長(zhǎng)度排序

#include <stdio.h>
#include <stdlib.h>
int cmp_char_strlen(const void* e1, const void* e2)//比較字符串長(zhǎng)度
{
    return strlen(*(char**)e1) - strlen(*(char**)e2);//先將e1和e2強(qiáng)制類(lèi)型轉(zhuǎn)換成為char**類(lèi)型,再解引用取出數(shù)組中字符串的地址,計(jì)算字符串長(zhǎng)度
}
int main()
{
    //char* arr[] = {"abcdef" "abc","defs" };
    //也可以通過(guò)下面的方式來(lái)寫(xiě)指針數(shù)組,下面的4行和上面的這一行作用一樣
    char* arr1 = "abc";
    char* arr2 = "abcd";
    char* arr3 = "abcdef";
    char* arr[] = { arr1,arr2,arr3 };
    int i = 0;
    qsort(arr, 3, sizeof(char*), cmp_char_strlen);
    for (i = 0; i < 3; i++)
    {
        printf("%s\n", arr[i]);//輸出結(jié)果為 abc  defs  abcdef
    }
    return 0;
}

4.浮點(diǎn)型數(shù)組排序

#include <stdio.h>
#include <stdlib.h>
int cmp_float(const void* e1, const void* e2)//浮點(diǎn)型數(shù)組排序
{
    //return (int)(*(float*)e1 - *(float*)e2);//可能會(huì)出錯(cuò),如12.002和12.001比較之后再?gòu)?qiáng)制類(lèi)型轉(zhuǎn)換為int類(lèi)型后,結(jié)果為0
    if (*(float*)e1 - *(float*)e2 > 0.000000)
    {
        return 1;//當(dāng)e1>e2時(shí),返回大于0的數(shù)
    }
    if (*(float*)e1 - *(float*)e2 < 0.000000)
    {
        return -1;//當(dāng)e1<e2時(shí),返回小于0的數(shù)
    }
    else
        return 0;//當(dāng)e1和e2相等時(shí),返回等于0的數(shù)
}
int main()
{
    float arr[3] = { 12.01f,12.03f,12.09f };
    int sz = sizeof(arr) / sizeof(arr[0]);//計(jì)算數(shù)組長(zhǎng)度
    qsort(arr, sz, sizeof(float), cmp_float);
    int i = 0;
    for (i = 0; i < sz; i++)
    {
        printf("%f  ", arr[i]);//輸出結(jié)果為12.010000  12.030000  12.090000
    }
    return 0;
}

5.結(jié)構(gòu)體類(lèi)型排序

#include <stdio.h>
#include <stdlib.h>
struct stu
{
    char name[20];
    int age;
};
int cmp_s_age(const void* e1, const void* e2)//比較結(jié)構(gòu)體中int類(lèi)型
{
    return ((struct stu*)e1)->age - ((struct stu*)e2)->age;
}
int cmp_s_name(const void* e1, const void* e2)//比較結(jié)構(gòu)體中char類(lèi)型的數(shù)組
{
    return strcmp(((struct stu*)e1)->name, ((struct stu*)e2)->name);
}
int main()
{
    struct stu s[] = { {"zhangsan",21} ,{"lisi",20},{"wangwu",52}};
    int i = 0;
    int sz = sizeof(s) / sizeof(s[0]);
    for (i = 0; i < sz; i++)
    {
        printf("%s %d\n", s[i].name, s[i].age);
    }
    qsort(s, sz, sizeof(struct stu), cmp_s_age);//比較年齡,即比較int類(lèi)型
    //qsort(s, sz, sizeof(struct stu), cmp_s_name);//比較姓名,即比較char類(lèi)型的數(shù)組
    printf("\n");
    for (i = 0; i < sz; i++)
    {
        printf("%s %d\n", s[i].name, s[i].age);//輸出為年齡按照升序排列,如果比較姓名,則按照姓名的首字符的ASCII值按照升序排列
    }
    return 0;
}

三、冒泡排序?qū)崿F(xiàn)qsort函數(shù)的功能

1.冒泡排序簡(jiǎn)介

冒泡排序是通過(guò)對(duì)兩個(gè)相鄰元素進(jìn)行比較,如果不符合條件就相互交換位置,并與后面相鄰的元素再次比較,直至滿(mǎn)足條件為止。

對(duì)于冒泡排序,如果它有n個(gè)元素,它將進(jìn)行n-1次的循環(huán)。冒泡排序的缺點(diǎn)是只能對(duì)整型數(shù)組進(jìn)行排序。

我們通過(guò)對(duì)整型數(shù)組排序進(jìn)一步了解冒泡排序

//用冒泡排序?qū)φ蛿?shù)組進(jìn)行排序
#include <stdio.h>
int main()
{
    int i = 0;
    int j = 0;
    int arr[] = { 7,8,9,4,5,6,1,2,3,10 };
    int sz = sizeof(arr) / sizeof(arr[0]);
    for (i = 0; i < sz-1; i++)//總共循環(huán)sz-1次
    {
        int flag = 1;//標(biāo)記,假設(shè)數(shù)組是有序的
        for (j = 0; j < sz - 1 - i; j++)//第一個(gè)元素需要和剩余的sz-1個(gè)元素比較,第二個(gè)元素需要和sz-1-1個(gè)元素比較……所以每次循環(huán)需要比較的次數(shù)為sz-1-i
        {
            if (arr[j] < arr[j + 1])//從大到小排列
            {
                int tmp = arr[j + 1];
                arr[j + 1] = arr[j];
                arr[j] = tmp;
                flag = 0;//倘若發(fā)生交換說(shuō)明數(shù)組是無(wú)序的
            }
        }
        if(flag == 1)
        {
            break;//如果沒(méi)發(fā)生一次交換說(shuō)明數(shù)組已經(jīng)是符合要求的有序數(shù)組
        }
    }
    for (i = 0; i < sz; i++)
    {
        printf("%d ", arr[i]);//輸出結(jié)果為 10 9 8 7 6 5 4 3 2 1
    }
    return 0;
}

2.冒泡排序?qū)崿F(xiàn)qsort函數(shù)功能

對(duì)冒泡排序進(jìn)行qsort化時(shí),要參照qsort函數(shù)的參數(shù),盡量做到參數(shù)一致。

void qsort_bubble(void* base, int sz, int width, int(*cmp)(const void* e1, const void* e2))

void* base表示對(duì)應(yīng)數(shù)組元素的起始位置。

int sz表示數(shù)組中元素總個(gè)數(shù)。

int width表示數(shù)組中每個(gè)元素所占字節(jié)數(shù)。

int(*cmp)(const void* e1, const void* e2)是函數(shù)指針,指向比較兩個(gè)元素大小的函數(shù)。

設(shè)計(jì)的冒泡排序qsort化函數(shù)qsort_bubble與庫(kù)函數(shù)qsort的參數(shù)意義相同。在qsort_bubble和qsort參數(shù)中函數(shù)指針指向的用于比較數(shù)組中兩個(gè)元素大小的函數(shù)不用發(fā)生改變,可以直接引用。

利用冒泡排序思想實(shí)現(xiàn)qsort函數(shù)功能并對(duì)結(jié)構(gòu)體排序。

#include <stdio.h>
struct stu
{
	char name[20];
	int age;
};
int cmp_s_age(const void* e1, const void* e2)//比較結(jié)構(gòu)體中整型
{
	return ((struct stu*)e1)->age - ((struct stu*)e2)->age;
}
int cmp_s_name(const void* e1, const void* e2)//比較結(jié)構(gòu)體中整型
{
	return strcmp(((struct stu*)e1)->name, ((struct stu*)e2)->name);
}
void Swap(char* buf1, char* buf2, int width)
{
	int i = 0;
	for (i = 0; i < width; i++)//一個(gè)字節(jié)一個(gè)字節(jié)的交換
	{
		char tmp = *buf1;
		*buf1 = *buf2;
		*buf2 = tmp;
		buf1++;
		buf2++;
	}
}
void qsort_bubble(void* base, int sz, int width, int(*cmp)(const void* e1, const void* e2))
{
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (cmp((char*)base + j * width, (char*)base + (j + 1) * width)>0)
				//強(qiáng)制轉(zhuǎn)換成char*類(lèi)型的指針,進(jìn)行交換時(shí)一個(gè)字節(jié)一個(gè)字節(jié)的交換,+width,向后走對(duì)應(yīng)的字節(jié)
			{
				Swap((char*)base + j * width, (char*)base + (j + 1) * width,width);//滿(mǎn)足條件進(jìn)行交換
			}
		}
	}
}
int main()
{
	struct stu s[] = { {"zhangsan",21} ,{"lisi",20},{"wangwu",52}};
	int i = 0;
	int sz = sizeof(s) / sizeof(s[0]);
	//printf("%d", sz);
	for (i = 0; i < sz; i++)
	{
		printf("%s %d\n", s[i].name, s[i].age);
	}
	qsort_bubble(s, sz, sizeof(struct stu), cmp_s_age);//比較年齡,即比較int類(lèi)型
	//qsort_bubble(s, sz, sizeof(struct stu), cmp_s_name);//比較姓名,即比較char類(lèi)型的數(shù)組
	printf("\n");
	for (i = 0; i < sz; i++)
	{
		printf("%s %d\n", s[i].name, s[i].age);
	}
	return 0;
}

原文鏈接:https://blog.csdn.net/weixin_53943591/article/details/127168902

欄目分類(lèi)
最近更新