C语言qsort函数详解和冒泡排序的模拟实现

C语言qsort函数详解

在这里插入图片描述

void *base ——— 目标数组的首地址
size_t num ——— 数组元素个数
size_t width ——— 元素所占的字节大小
int (__cdecl *compare )(const void *elem1, const void *elem2 ) ——— 一个函数指针(下面会详解)

int (__cdecl *compare )(const void *elem1, const void *elem2 )详解

下面将 (__cdecl *compare )简化为(cmp )
*elem1简化为e1
*elem2简化为e2

*e1详解

在这里插入图片描述

指向搜索键的指针

*e2详解

在这里插入图片描述

指向要与键进行比较的数组元素的指针

返回值

在这里插入图片描述

如上图所示
e1小于e2则返回一个小于0的数
e1等于e2则返回0
e1大于e2则返回一个大于0的数

使用实例

乱序变成有序

降序

排列一个整型数组

#include <stdio.h>
#include <stdlib.h>

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

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

	printf("排序前:\n");
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", array[i]);
	}
	qsort(array, sz, sizeof(array[0]), cmp);

	printf("排序后:\n");
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", array[i]);
	}
	return 0;
}

在这里插入图片描述

有的眼尖的就发现,其实cmp函数的返回值可以写得更简单

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

那么一样的可以得到相同的效果,也没有让代码显得那么复杂

升序

根据没有更改之前的代码,可以知道,如果需要升序就讲e1和e2反过来

return *(int* )e2 - *(int* )e1

用库函数qsort设计思想实现冒泡排序

冒泡排序

先实现一般的冒泡排序

#include <stdio.h>
int main()
{
	int array[] = { 2,3,5,6,4,8,7,9,1 };
	int sz = sizeof(array) / sizeof(array[0]);
	
	printf("排序前:\n");
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", array[i]);
	}
	putchar('\n');
	// 冒泡排序
	for (int i = 0; i < sz; i++)
	{
		for (int j = 0; j < sz - i - 1; j++)
		{
			if (array[j] > array[j + 1])
			{
				int tmp = array[j];
				array[j] = array[j + 1];
				array[j + 1] = tmp;
			}
		}
	}

	printf("排序后:\n");
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", array[i]);
	}
	return 0;
}

在这里插入图片描述

实现思路

  1. 冒泡排序设置4个参数
  2. 想一个如何应对接收不同数据类型的比较函数
  3. 想一个能够接收不同数据类型的比较函数

代码

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

void swap(char* p1, char* p2, int width)
{
	for (int i = 0; i < width; i++)
	{
		char tmp = *p1;
		*p1 = *p2;
		*p2 = tmp;
		*p1++, *p2++;
	}

}
void Babble_sort(void* array, int sz, int width, int(*cmp)(const void* e1, const void* e2))
{
	for (int i = 0; i < sz; i++)
	{
		for (int j = 0; j < sz - i - 1; j++)
		{
			if (cmp((char*)array + width * j, (char*)array + width * (j + 1)) > 0)
			{
				swap((char*)array + width * j, (char*)array + width * (j + 1), width);

			}
		}
	}
}

#include <stdio.h>
int main()
{
	int array[] = { 2,3,5,6,4,8,7,9,1 };
	int sz = sizeof(array) / sizeof(array[0]);
	printf("排序前:\n");
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", array[i]);
	}
	putchar('\n');


	Babble_sort(array, sz, sizeof(array[0]), cmp);

	printf("排序后:\n");
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", array[i]);
	}
	putchar('\n');
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值