【C语言】qsort函数的使用

👑个人主页:啊Q闻

🎇收录专栏:《C语言》

🎉道阻且长,行则将至

前言

这篇博客主要是介绍qsort函数的使用,以及利用冒泡排序的方式模拟实现qsort

一.初识qsort函数

我们可以在qsort - C++ Reference (cplusplus.com)了解到qsort函数,我们发现

void*base是指要排序的数组中的第一个元素 ,利用void*是因为void*为泛指型指针,所以不论什么类型都可以接收,这也正是qsort函数的一大好处,qsort函数可以实现任意类型函数的排序

size_t num是指数组中的元素个数

size_t size是指指向中的元素的大小

int(*compar)(const void*,const void*)则是需要使用者自己创造一个函数实现数组中元素的大小比较,当返回值大于0时,前者大于后者,当返回值小于0时,前者小于后者,当返回值为0时,前者等于后者。

二.利用qsort函数排序

1.使用qsort函数排序整型数据

cpp 复制代码
#include<stdio.h>
int int_cmp(const void* p1, const void* p2)
{
	return(*(int*)p1 - *(int*)p2);//详解1
}
int main()
{
	int arr[] = { 1,3,5,6,7,2,4,9,8,0};
	int i = 0;
	qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(arr[0]), int_cmp);
	for (i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	return 0;
 }

详解1:void*的指针不可以直接进行指针的加减整数和解引用的计算,所以在这里我们要强制性转换int*。

2.利用qsort函数排序结构数据

因为结构体中有不只有一个成员,所以要相同的成员之间比较,因此会有多种比较方法

cpp 复制代码
#include<stdio.h>
#include<string.h>
struct Stu
{
	char name[20];
	int age;
};
int cmp_by_name(const void* p1, const void* p2)//按照名字排序
{
	return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p1)->name);
}
int cmp_by_age(const void* p1, const void* p2)//按照年龄排序
{
	return ((struct Stu*)p1)->age-((struct Stu*)p2)->age;
}
void test2()
{
	struct Stu s[] = { {"zhangsan",20},{"lisi",30},{"wangwu",15} };
	qsort(s, sizeof(s) / sizeof(s[0]), sizeof(s[0]), cmp_by_name);
	int i = 0;
	for (i = 0; i < sizeof(s) / sizeof(s[0]); i++)
	{
		printf("%s %d  ", s[i].name, s[i].age);
	}
	printf("\n");
}
void test3()
{

	struct Stu s[] = { {"zhangsan",20},{"lisi",30},{"wangwu",15} };
	qsort(s, sizeof(s) / sizeof(s[0]), sizeof(s[0]), cmp_by_age);
	int i = 0;
	for (i = 0; i < sizeof(s) / sizeof(s[0]); i++)
	{
		printf("%s %d  ", s[i].name, s[i].age);
	}
}
int main()
{
	test2();
	test3();
	return 0;
}

详解:因为名字为字符串,所以要用strcmp进行比较。

三.qsort函数的模拟实现

在这里,我们采用冒泡排序的方式实现qsort 。

1.qsort实现整数排序

cpp 复制代码
#include<stdio.h>
void int_cmp(const void* p1, const void* p2)
{
	return(*(int*)p1 - *(int*)p2);
}
void Swap(void* p1, void* p2, size_t  size)
{
   int i = 0;
   for (i = 0; i < size; i++)
  {
	char tmp = *((char*)p1+i);
    *((char*)p1+i) = *((char*)p2+i);
    *((char*)p2+i) = tmp;
  }
}
void bubble(void* base, int count, int size, int(*cmp)(const void*, const void*))
{
	int i = 0;
	int j = 0;
	for (i = 0; i < count - 1; i++)
	{
		for (j = 0; j < count - i - 1; j++)
		{

			if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
			{
				Swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
			}
		}
	}
}
		
		int main()
		{
			int arr[10] = { 1,3,5,2,4,6,9,8,7,0 };
			int i = 0;
			int sz = sizeof(arr) / sizeof(arr[0]);
			bubble(arr, sz, sizeof(arr[0]), int_cmp);
			for (i = 0; i < sz; i++)
			{
				printf("%d ", arr[i]);
			}
			printf("\n");
			return 0;
		}

详解:

2.qsort实现结构排序

结构体排序类似整型排序,代码放在下方:

cpp 复制代码
 #include<stdio.h>
struct Stu
{
	char name[20];
	int age;
};
int cmp_by_age(void* p1, void* p2)
{
	return((struct Stu*)p1)->age - ((struct Stu*)p2)->age;
}
int cmp_by_name(void* p1, void* p2)
{
	return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);
}
void Swap(void* p1, void* p2, size_t  size)
{
	int i = 0;
	for (i = 0; i < size; i++)
	{
		char tmp = *((char*)p1+i);
	*((char*)p1+i) = *((char*)p2+i);
	*((char*)p2+i) = tmp;
    }
}
void bubble(void* base, int count, int size, int(*cmp)(const void*, const void*))
{
	int i = 0;
	int j = 0;
	for (i = 0; i < count - 1; i++)
	{
		for (j = 0; j < count - i - 1; j++)
		{

			if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
			{
				Swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
			}
		}
	}
}
		
		int main()
		{
			struct Stu arr[] = { {"zhangsan",18},{"lisi,22"},{"wangwu",11} };
			int i = 0;
			int sz = sizeof(arr) / sizeof(arr[0]);
			bubble(arr, sz, sizeof(arr[0]), cmp_by_age);
			for (i = 0; i < sz; i++)
			{
				printf("%s %d ",arr[i].name,arr[i].age);
			}
			printf("\n");
			return 0;
		}

谢谢你的阅读,如果对你有帮助的,三连么么么

相关推荐
IvanCodes1 小时前
Python 数据处理(十三):JSON、CSV 与数据序列化
开发语言·python
aramae2 小时前
MySQL复合查询(8)
java·c语言·开发语言·后端·算法
无敌贵点大王3 小时前
RTThread学习记录11——RT-Thread 设备模型吃透:UART/ADC/PWM/PIN 到底有什么区别?
c语言·stm32·学习·链表
Logic1014 小时前
C语言/数据结构位运算题解:异或XOR找出时尚聚会中的“独特颜色“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
qq_2518364575 小时前
springboot vue3 开发实现 拼豆管理系统
java·开发语言·ai编程
郑州光合科技余经理6 小时前
同城外卖小程序开发:下单成功后,后台导出能不能对上用户端状态
开发语言·前端·git·后端·uni-app·php·ai编程
知识分享小能手6 小时前
C++ 学习教程,从入门到精通,C++ 入门知识 — 完整知识点(1)
开发语言·c++·学习
+VX:Fegn08956 小时前
计算机毕业设计|基于springboot + vue旅游管理系统(源码+数据库+文档)
java·开发语言·vue.js·spring boot·课程设计
阿里嘎多学长7 小时前
2026-09-20 GitHub 热点项目精选
开发语言·程序员·github·代码托管
Escalating_xu8 小时前
【C 语言项目】数组和函数综合实践:从零实现控制台扫雷游戏
c语言