课外拓展2.实现qsort函数及模拟实现qsort函数

qsort函数和qsort函数的模拟实现

目录

一,qsort函数的实现

二,qsort函数的模拟实现


一,qsort函数的实现

#define _CRT_SECURE_NO_WARNINGS 1
//qsort函数
#include<stdio.h>
#include<stdlib.h>
void print(int arr[], int sz) {
	for (int i = 0; i < sz; i++)
		printf("%d ",arr[i]);
	printf("\n");
}

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

int main() {
	int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	//排序
	qsort(arr,sz,sizeof(arr[0]),compare);
	//输出
	print(arr, sz);


	return 0;
}
//qsort函数的基本结构(快速排序)
//void qsort(void* base, size_t num, size_t size, int (*compare)(const void*, const void*));
//void* base指的是排序数据首元素的地址。
//size_t num指的是排序数据的个数;
//size_t size指的是每个元素的大小(占几个字节);因为传进来的数据首元素的类型未知,需要认为的输入字节大小;
//int (*compare)(const void*, const void*)指的是一个函数指针;指向一个函数。这个是留给使用者写的自定义函数。
//因为qsort函数适用于所有类型的比较排序,所以指针类型都是void,但是使用者是一定知道比较的数据类型,故把这个函数留给使用者写
//
//int compare(const void* e1, const void* e2) {
//	return *(int*)e1 - *(int*)e2;
//}
//我们来分析一下这个该由我们自己书写的函数
//首先,参数是两个无类型的空指针,代表着这个函数可以用于任何类型的数据相比较
//这个函数的返回值一定是int整型,因为在qsort函数中是根据这个函数的返回值进行排序的,返回值大于0是就是升序排序,
//返回值小于0就是降序排序。

qsort函数的基本结构(快速排序)
void qsort(void* base, size_t num, size_t size, int (*compare)(const void*, const void*));
void* base指的是排序数据首元素的地址。
size_t num指的是排序数据的个数;
size_t size指的是每个元素的大小(占几个字节);因为传进来的数据首元素的类型未知,需要认为的输入字节大小;
        int (*compare)(const void*, const void*)指的是一个函数指针;指向一个函数。这个是留给使用者写的自定义函数。
        因为qsort函数适用于所有类型的比较排序,所以指针类型都是void,但是使用者是一定知道比较的数据类型,故把这个函数留给使用者写

int compare(const void* e1, const void* e2) {
    return *(int*)e1 - *(int*)e2;
}
        我们来分析一下这个该由我们自己书写的函数
首先,参数是两个无类型的空指针,代表着这个函数可以用于任何类型的数据相比较
            这个函数的返回值一定是int整型,因为在qsort函数中是根据这个函数的返回值进行排序的,返回值大于0是就是升序排序,
返回值小于0就是降序排序。

二,qsort函数的模拟实现

//模拟实现qsort函数
#include<stdio.h>
//交换函数(也可以不单独写成函数,但是我觉得主要可读性更好)
void swap(char* buf1, char* buf2,size_t width) {
	int i;
	for (i = 0; i < width; i++) {
		char temp = *buf1;
		*buf1 = *buf2;
		*buf2 = temp;
		buf1++;
		buf2++;
	}
}
//写qsort必须写的函数,必须由使用者写,虽然我们这里是模拟实现qsort函数,但是仍需要写这个。
int compare(const void* e1, const void* e2) {

	//根据返回值进行排序(来绝对是升序还是降序)
	return *(char*)e1 - *(char*)e2;
}
void bubble_sort(void* base, size_t sz, size_t width, int (*compare)(const void*, const void*)) {
	int i, j;

	//外层循环控制总趟数
	for (i = 0; i < sz-1; i++) {//这里一定是sz减一,sz是数组长度,下标只能到sz-1;


		for (j = 0; j < sz - i- 1; j++) {


			//这个地方是妥妥的重点了,为什么要强制类型转换为char* 类型?
			//其实这个地方我觉得转换为其他类型也行,但是qsort函数是可以对所有数据类型进行排序的,如果只是对单一的一种数据排序,那的确是可以的
			//但是我们这里是模拟实现qsort函数的功能,故,我们这里转换为char* 类型
			//还有一个原因,char*类型的指针解引用时只走一个字节,众所周知,字节是代码的最小存储单位了,其他无论什么类型的数据都是以字节论的

			if (compare((char*)base + j * width, (char*)base + (j + 1) * width) > 0)

				swap(((char*)base + j * width), ((char*)base + (j + 1) * width),width);

			//我们再来理解一下这个(char*)base + j * width是什么意思呢?
			//首先这个char*我是已经将过了的,接下来我们要解释的就是j*width的含义
			//因为我们对未知类型的数据进行排序,(int*)+1是走四个字节,但对它本身来说就只移动了一个元素长度
			//那如果是(int*)+i呢?我们是不是就可以理解为从头开始往后面走了i个元素,拿这个例子与上面一对比,这就十分明确了
			//j*width的意思就是待排序数据一个元素所占用的长度,也就是往后面移动了一位。

		}
	}
}

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

	bubble_sort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(arr[0]), compare);

	int i = 0;
	for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
		printf("%d",arr[i]);
	}
	printf("\n");

	char arr1[] = "hello world";//这里我准备了两个例子供大家参考

	bubble_sort(arr1, sizeof(arr1) / sizeof(arr1[0]), sizeof(arr1[0]), compare);

	for (i = 0; i < sizeof(arr1) / sizeof(arr1[0]); i++)
		printf("%c",arr1[i]);
	printf("\n");

	return 0;
}

qsort函数,俗称快排,它可以对任意数据类型的数据进行排序,这是很方便的,希望大家一定要搞熟。

希望大家能学到东西,静待大家的斧正和指教。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喜欢吃豆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值