C 语言快速排序算法

3 篇文章 0 订阅

排序规则的原理


 C 语言提供的快速排序算法,内部包含4个参数,第一个参数是要排序数组的地址,第二个参数是数字的长度,第三个参数是数组元素的大小,第四个参数是回到函数:用来定义快速排序的规则。

在快速排序或任何其他比较排序算法中,比较函数决定了排序的方向。在你给出的代码片段中,val变量的赋值实际上定义了元素*a*b之间的相对大小,从而影响了排序结果。

*a > *b时,val被设为1;当*a < *b时,val被设为-1;当两者相等时,val被设为0

qsort()函数的上下文中,排序算法会基于val的值来决定如何交换元素。具体来说:

  • val1时(即*a > *b),这表示a应该排在b之后,以保持升序排列。如果ab之前,qsort()会将它们交换,使b在前,a在后。
  • val-1时(即*a < *b),这表示a应该排在b之前,以保持升序排列。如果a已经在b之前,那么不需要交换。
  • val0时(即*a == *b),意味着两个元素相等,无论它们的位置如何都不会改变排序状态。

因此,当qsort()使用这个比较函数时,它会根据val的值来调整元素位置,确保最终的结果是按升序排列的。这是因为qsort()在递归过程中会将较大的元素推到数组的右边,较小的元素推到左边,而等于的元素则维持原位,从而实现排序。

 注:以上的规则是基于升序排序而言降序排序是同样的原理,修改a 和 b 比较的符号即可。


升序排序


/*
   快速排序算法排序规则
*/
int32_t CmpCb(const void* _a, const void* _b)
{
	uint16_t* a = (uint16_t*)_a;
	uint16_t* b = (uint16_t*)_b;
	int32_t val = 0;
	if (*a > *b)
	{
		val = 1;
	}
	else if (*a < *b)
	{
		val = -1;
	}
	else 
	{
		val = 0;
	}
	return val;
}


int main() 
{
	// 创建局部数组
	uint16_t num[10] = { 5,7,8,1,26,52,9,3,14,56 };
	uint16_t sz = sizeof(num) / sizeof(num[0]);
	// C语言库函数提供的排序函数
	qsort(num, sz, sizeof(num[0]), CmpCb);
	// for循环打印输出排序玩成后的数据
	for (uint8_t i = 0; i < sz; i++) 
	{
		printf("num[%d] = %d.\n",i,num[i]);
	}
}

 结果:



降序排序


#define _CRC_SECURE_NO_WARNINGS
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

/*
   快速排序算法排序规则
*/

#if 0

	int32_t CmpCb(const void* _a, const void* _b)
	{
		uint16_t* a = (uint16_t*)_a;
		uint16_t* b = (uint16_t*)_b;
		int32_t val = 0;
		if (*a > *b)
		{
			val = 1;
		}
		else if (*a < *b)
		{
			val = -1;
		}
		else 
		{
			val = 0;
		}
		return val;
	}
#else
/*
   快速排序算法排序规则
*/
int32_t CmpCb(const void* _a, const void* _b)
{
	uint16_t* a = (uint16_t*)_a;
	uint16_t* b = (uint16_t*)_b;
	int32_t val = 0;
	if (*a > *b)
	{
		val = -1;
	}
	else if (*a < *b)
	{
		val = 1;
	}
	else
	{
		val = 0;
	}
	return val;
}

#endif

int main() 
{
	// 创建局部数组
	uint16_t num[10] = { 5,7,8,1,26,52,9,3,14,56 };
	uint16_t sz = sizeof(num) / sizeof(num[0]);
	// C语言库函数提供的排序函数
	qsort(num, sz, sizeof(num[0]), CmpCb);
	// for循环打印输出排序玩成后的数据
	for (uint8_t i = 0; i < sz; i++) 
	{
		printf("num[%d] = %d.\n",i,num[i]);
	}
}

结果:


结构体排序

#define _CRC_SECURE_NO_WARNINGS
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

// 排序结构体
typedef struct
{
	uint16_t id;
	uint8_t score;
}StuInfo_t;

#if 0

	int32_t CmpCb(const void* _a, const void* _b)
	{
		uint16_t* a = (uint16_t*)_a;
		uint16_t* b = (uint16_t*)_b;
		int32_t val = 0;
		if (*a > *b)
		{
			val = 1;
		}
		else if (*a < *b)
		{
			val = -1;
		}
		else 
		{
			val = 0;
		}
		return val;
	}
#else

/*
 快速排序算法排序规则
*/
int32_t CmpCb(const void* _a, const void* _b)
{
	uint16_t* a = (uint16_t*)_a;
	uint16_t* b = (uint16_t*)_b;
	int32_t val = 0;
	if (*a > *b)
	{
		val = -1;
	}
	else if (*a < *b)
	{
		val = 1;
	}
	else
	{
		val = 0;
	}
	return val;
}


int32_t StuCmpCb(const void* _a, const void* _b)
{
	StuInfo_t* a = (StuInfo_t*)_a;
	StuInfo_t* b = (StuInfo_t*)_b;
	int32_t val = 0;
	if (a->score > b->score)
	{
		val = -1;
	}
	else if (a->score < b->score)
	{
		val = 1;
	}
	else
	{
		val = 0;
	}
	return val;
}

#endif



int main() 
{
	// 创建局部数组
	uint16_t num[10] = { 5,7,8,1,26,52,9,3,14,56 };
	uint16_t sz = sizeof(num) / sizeof(num[0]);
	// C语言库函数提供的排序函数
	qsort(num, sz, sizeof(num[0]), CmpCb);
	// for循环打印输出排序玩成后的数据
	for (uint8_t i = 0; i < sz; i++) 
	{
		printf("num[%d] = %d.\n",i,num[i]);
	}
	// 定义一个结构体数组
	StuInfo_t stuInfo[5] =
	{
		{1,90},
		{2,95},
		{3,69},
		{4,70},
		{5,80}
	};
	// C语言库函数提供的排序函数
	qsort(stuInfo, 5, sizeof(stuInfo[0]), StuCmpCb);
	// for循环打印输出排序玩成后的数据
	for (uint8_t i = 0; i < 5; i++)
	{
		printf("student_id = %d, score = %d.\n", stuInfo[i].id, stuInfo[i].score);
	}

}

结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值