qsort函数的使用及模拟实现

qsort函数的介绍及简单使用案例

qsort函数介绍

在C语言中 qsort 函数用以对数据进行排序,默认是由小到大排序,其基本形式如下:

//base 值得是需要进行排序的数组
//num指的是数组中元素的个数
//size指的是数组中每个元素所占内存空间的大小
//compar是一个函数指针,该函数用来进行数据对比判断是否进行交换
void qsort (void* base, size_t num, size_t size,
            int (*compar)(const void*,const void*));

注意 只要写出compar函数代码,qsort函数可以排序任意数据类型的数组

qsort函数的简单使用举例

//头文件包含
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//主函数内容如下
int main()
{
	//使用qsort函数排序整型数组
	test1();
	//使用qsort函数排序自定义数组
	test2();

	return 0;
}
//int型数组排序方法
int cmp_int(const void* p1, const void* p2)
{
	//p1>p2 交换
	//p1<=p2 不交换
	return (*(int*)p1 - *(int*)p2);
}

void test1()
{
	int arr[] = { 0,5,7,6,1,3,4,9,8,2};
	int sz = sizeof(arr) / sizeof(arr[0]);//求数组中元素个数
	qsort(arr, sz, sizeof(arr[0]), cmp_int);
	
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
}

输出结果:
在这里插入图片描述

//自定义类型stu排序
struct stu
{
	char name[20];
	int age;
};

int cmp_stu_by_name(const void* p1,const void* p2)
{
	//这里是通过名字来排序,运用了strcmp函数进行比较
	//也可以用年龄来排序,具体可参考上面的整型数据排序代码
	return strcmp(((struct stu*)p1)->name, ((struct stu*)p2)->name);
}
void test2()
{
	struct stu arr[3] = { {"zhangsan",17},{"lisi",18},{"wangwu",16} };
	int sz = sizeof(arr) / sizeof(arr[0]);//求出数组元素个数
	qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_name);
}

运行结果如下:
在这里插入图片描述

运用冒泡排序模拟实现qsort函数

具体模拟实现过程

qsort函数底层用的是快速排序算法,这里我们使用冒泡排序进行模拟实现

//使用冒泡排序算法模拟实现qsort函数,要求能够排序任意数据类型数组

//实现交换函数
//e1指的是传过来元素的第一个字节的地址
//e2指的是下一个元素的第一个字节的地址

void swap(char* e1, char* e2, size_t width)
{
	//只要我们把元素中每个字节的内容都进行交换,那么整体上就交换了
	while (width--)
	{
		char tmp = *e1;
		*e1 = *e2;
		*e2 = tmp;
		e1++;
		e2++;
	}
}

//arr 指的是待排序数组,使用void* 类型可接收任意数据类型数组
//sz 指的是数组中需要排序的元素个数
//width 指的是数组中每个元素在内存中所占空间大小,单位是字节
//cmp 指的是函数使用者所写的判断是否交换两个元素的方法,需要交换返回大于0的数字,不需要返回0或者小于0的数字

void bubble_sort(void* arr, size_t sz, size_t 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 - i - 1; j++)
		{
				//这里需要把arr强制类型转换为char*类型,因为我们需要对每个字节进行操作
				//(char*)arr + (j * width)指的是数组中某个元素的第一个字节的地址
				//(char*)arr + (j + 1) * width)指的是下一个元素的第一个字节的地址
			if ((cmp(((char*)arr + (j * width)), ((char*)arr + ((j + 1) * width))) > 0))
			{
				swap(((char*)arr + (j * width)), ((char*)arr + ((j + 1) * width)), width);
			}
		}
	}
}

案例展示

//int型数组排序方法
int cmp_int(const void* p1, const void* p2)
{
	return (*(int*)p1 - *(int*)p2);
}

void test1()
{
	int arr[] = { 0,5,7,6,1,3,4,9,8,2 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);//使用自己模拟的函数进行排序
	
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
}

结果如下:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值