震惊!!qsort函数还能这么玩?--(超详解)

前言:

之前介绍了指针的一些内容,也学习了冒泡排序的方法,但是冒泡排序仅针对整形来排序,并且每次还需要手写,有没有一个函数,既可以排任意类型的数据,又能直接调用,它就是---qsort函数。

gogogo


目录:

1.什么是qsort函数

2.qsort函数怎么用

3.qsort和冒泡排序的对比


正文:

1.什么是qsort函数

qsort 是 C 语言标准库中的一个快速排序函数,它位于 stdlib.h 头文件中。它的返回值类型是 void,因为 qsort 函数直接对传入的数组进行排序,不会返回排序后的数组。

我们可以通过cplusplus这个网站查看库函数(qsort)的函数参数类型:

qsort函数有四个参数:

1.void* base:它指向要排序函数的第一个数组元素的指针。(因为不知道要排序的是什么类型,参数为(void*))。

2.size_t num:它是要排序数组的元素个数。可以用sizeof(数组名)/sizeof(第一个元素)求出。返回类型是size_t类型,因为元素个数不可能为负。

3.size_t  size:它是要排序的一个元素字节大小。可以用sizeof(第一个元素)求出。

4.int*(cmp)(const void*,const void*):它是一个函数指针,指向一个比较函数,该比较函数比较两个元素的大小。

 

2.qsort函数怎么用

好,上面看不懂你先别慌,我们知道了qsort函数的参数类型,现在我们来解锁一下qsort函数的用法,你就会啦~

想要完成qsort函数,我们使用者必须提供一个函数接口(cmpareMyType),这个函数接口就是我们想比较的数据类型的两个数据,想要比较整形,就比较整形的两个数据的大小,想要比较结构体,就比较结构体的两个数据的大小。那么有一个规则:我们可以参考

也就是,如果第一个数<第二个数,返回-1;第一个数等于第二个数,返回0 ;第一个数>第二个数,返回1

我们现在来完成(cmpareMyType)这个函数来比较整形

int cmp_int(const void* e1, const void* e2)
{
    if (*(int*)e1 > *(int*)e2)
        return  1;
    else if ((*(int*)e1 < *(int*)e2))
        return -1;
    else
        return 0;
}

当然:这种写法显然很冗余了,我们还可以这样写:

int cmp_int(const void* e1, const void* e2)
{
	return *(int*)e1 - *(int*)e2;
}

到这里,你已经成功了80%了,下面我们就根据它的规则套模版就行了。


qsort排序整形:

再说一遍规则:我们把我们要排序的数组按qsort函数的参数一一传给它,然后我们再自已实现一个要比较的数据类型的函数就搞定了(上面已经实现啦):

不要忘记头文件(<stdlib.h>)

#include <stdio.h>
#include <stdlib.h>
int cmp_int(const void* e1, const void* e2)
{
	return *(int*)e1 - *(int*)e2;
}
int main()
{
	int arr[] = { 2,5,1,7,9,6,4,8,10,3 };//无序数组
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), cmp_int);//qsort排序整形
	//打印
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

是不是很神奇,我们什么也没干,qsort函数就帮我们排序好了。接着我们再试一下qsort函数排序字符型,结构体类型。

qsort排序字符型:

#include <stdio.h>
#include <stdlib.h>
int cmp_char(const void* e1, const void* e2)
{
	return *(char*)e1 - *(char*)e2;
}
int main()
{
	char str[] = {'a','s','b','e','h','g','\0'};//无序数组
	int sz = sizeof(str) / sizeof(str[0]);
	qsort(str, sz, sizeof(str[0]), cmp_char);//qsort排序字符形
	//打印
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%c ", str[i]);
	}
	return 0;
}

qsort排序结构体类型

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Stu
{
	int age;
	char name[10];
};
//e1指向一个结构体对象,e2指向一个结构体对象
int cmp_name(const void* e1, const void* e2)
{
	return strcmp( ((struct Stu*)e1)->name , ((struct Stu*)e2)->name);//结构体指针->成员
}
int main()
{
	struct Stu s[] = { {19,"zhangsan"},{17,"lisi"},{30,"wangwu"} };//结构体无序数组
	int sz = sizeof(s) / sizeof(s[0]);
	qsort(s, sz, sizeof(s[0]), cmp_name);//qsort排序结构体
	//打印
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("name:%s\n", s[i].name);
	}
	return 0;
}

 哎,确实很神奇,只需要任意数据类型数组中的两个元素,就能排序整个数组。

4.qsort和冒泡排序的对比

我们可以对比一下冒泡排序和qsort函数排序整形

下面是冒泡排序的排序方式:

void bubble_sort(int arr[], int sz)//参数接收数组元素个数 
{
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		int flag = 1;//假设这⼀趟已经有序了 
		int j = 0;
		for (j = 0; j < sz - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				flag = 0;//发⽣交换就说明,⽆序 
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
		if (flag == 1)//这⼀趟没交换就说明已经有序,后续⽆序排序了 
			break;
	}
}
int main()
{
	int arr[] = { 3,1,7,5,8,9,0,2,4,6 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr, sz);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

 我们很显然能发现,qsort函数比起冒泡排序使用起来方便快捷,但是我们并不能忘掉冒泡排序的思想。为了有耐心学下去,我把qsort函数的模拟实现放到了下一篇,希望大家一定要学会qsort函数的使用。好啦~欲知后事如何,请看下篇分解~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值