模拟实现qsort函数(冒泡排序版本)

作者:~小明学编程

文章专栏:C语言基础知识

目之所及皆为回忆,心之所想皆为过往
在这里插入图片描述

今天给大家介绍C语言中一个比较好用的函数qsort函数以及我们模拟实现qsort函数的过程。

目录

qsort函数

作用

参数

用法

模拟实现qsort函数


qsort函数

这里是qsort函数的介绍,在这里简单的给大家翻译介绍一下

作用

首先最上面说到它的作用,执行一个快速排序,qsort函数是一个排序函数,它的底层排序算法是快速排序。

参数

void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *elem1, const void *elem2 ) );

接着就是它的返回值和参数,我们可以看到这长长的一串,看着就头疼,不过也没大家想象的那么复杂,给大家介绍一下大家就明白了。

首先看我们的第一个参数base,就是一个我们待排序的数组,接着就是num,顾名思义就是我们数组元素的的大小,待排序元素的个数,然后就是width参数,也就是我们待排元素中每个元素的大小,最后就是int (__cdecl *compare )(const void *elem1, const void *elem2 )这是一个回调函数,其中compare是一个函数指针,函数的两个参数分别是elem1和elem2(类型是void*)返回值是int类型,最后qsort的返回类型是void型。

用法

下面就给大家介绍一下qsot函数的用法

//整数的比较
int cmp1(const void* e1, const void* e2)
{
	return *((int*)e1) - *((int*)e2);
}
//测试整数
void test1()
{
	int arr[5] = { 5,4,3,2,1 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	my_qsort(arr, sz, sizeof(arr[0]), cmp1);
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");

}
int main()
{
	test1();
	return 0;
}

这个比较函数是需要我们自己去设计的,根据我们所比较的类型不同我们可以设计不同的比较函数

//浮点数的比较
int cmp2(const void* e1, const void* e2)
{
	return *((double*)e1) - *((double*)e2);
}
//字符的比较
int cmp3(const void* e1, const void* e2)
{
	return *((char*)e1) - *((char*)e2);
}
//字符串的比较
int cmp4(const void* e1, const void* e2)
{
	return strcmp(*(char**)e1, *(char**)e2);
}
//结构体数字比较
int cmp5(const void* e1, const void* e2)
{
	return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
//结构体字符串比较
int cmp6(const void* e1, const void* e2)
{
	return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}

下面是我们对一个整数数组的排序

模拟实现qsort函数

//模拟实现qsort函数
void swap(char* ch1, char* ch2, int sz)
{
	for (int i = 0; i < sz; i++)
	{
		char tem = *ch1;
		*ch1 = *ch2;
		*ch2 = tem;
		ch1++;
		ch2++;
	}
}
void my_qsort(void* arr, int num, int size, int (*cmp)(const void* e1, const void* e2))
{
	for (int i = 0; i < num; i++)
	{
		for (int j = 0; j < num - i - 1; j++)
		{
			//cmp((char*)arr + j * size, (char*)arr + (j + 1) * size)
			if (cmp((char*)arr + j * size, (char*)arr + (j + 1) * size))
			{
				swap((char*)arr + j * size, (char*)arr + (j + 1) * size, size);
			}
		}
	}
}

其中我们判断大小之后要进行一个交换,交换的过程我们采用的是逐个字节进行交换,也就是我们的swap函数所实现的功能。

下面是我们对各种类型的比较

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct Stu
{
	int age;
	char name[20];
};
//整数的比较
int cmp1(const void* e1, const void* e2)
{
	return *((int*)e1)-*((int*)e2);
}
//浮点数的比较
int cmp2(const void* e1, const void* e2)
{
	return *((double*)e1) - *((double*)e2);
}
//字符的比较
int cmp3(const void* e1, const void* e2)
{
	return *((char*)e1) - *((char*)e2);
}
//字符串的比较
int cmp4(const void* e1, const void* e2)
{
	return strcmp(*(char**)e1, *(char**)e2);
}
//结构体数字比较
int cmp5(const void* e1, const void* e2)
{
	return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
//结构体字符串比较
int cmp6(const void* e1, const void* e2)
{
	return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}

//模拟实现qsort函数
void swap(char* ch1, char* ch2, int sz)
{
	for (int i = 0; i < sz; i++)
	{
		char tem = *ch1;
		*ch1 = *ch2;
		*ch2 = tem;
		ch1++;
		ch2++;
	}
}
void my_qsort(void* arr, int num, int size, int (*cmp)(const void* e1, const void* e2))
{
	for (int i = 0; i < num; i++)
	{
		for (int j = 0; j < num - i - 1; j++)
		{
			//cmp((char*)arr + j * size, (char*)arr + (j + 1) * size)
			if (cmp((char*)arr + j * size, (char*)arr + (j + 1) * size))
			{
				swap((char*)arr + j * size, (char*)arr + (j + 1) * size, size);
			}
		}
	}
}
//测试整数
void test1()
{
	int arr[5] = { 5,4,3,2,1 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	my_qsort(arr, sz, sizeof(arr[0]), cmp1);
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");

}

//测试浮点数
void test2()
{
	double arr[5] = { 2.5,2.3,3.8,6.1,0.2 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	my_qsort(arr, sz, sizeof(arr[0]), cmp2);
	for (int i = 0; i < 5; i++)
	{
		printf("%.1lf ", arr[i]);
	}
	printf("\n");
}
//测试字符
void test3()
{
	char arr[5] = { 'e','f','o','a','q' };
	int sz = sizeof(arr) / sizeof(arr[0]);
	my_qsort(arr, sz, sizeof(arr[0]), cmp3);
	for (int i = 0; i < 5; i++)
	{
		printf("%c ", arr[i]);
	}
	printf("\n");
}
//测试字符串
void test4()
{
	char* arr[] = { "shan","huani","ajfie","deygufefb" };
	int sz = sizeof(arr) / sizeof(arr[0]);
	my_qsort(arr, sz, sizeof(arr[0]), cmp4);
	for (int i = 0; i < sz; i++)
	{
		printf("%s ", arr[i]);
	}
	printf("\n");
}
//测试结构体中的排序
void test5()
{
	struct Stu arr[4] = { {11,"uheriu"},{37,"iuehen"},{8,"aouenioon"},{22,"ming"} };
	int sz = sizeof(arr) / sizeof(arr[0]);
	my_qsort(arr, sz, sizeof(arr[0]), cmp5);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i].age);
	}
	printf("\n");
	my_qsort(arr, sz, sizeof(arr[0]), cmp6);
	for (int i = 0; i < sz; i++)
	{
		printf("%s ", arr[i].name);
	}
}
int main()
{
	test1();
	test2();
	test3();
	test4();
	test5();
	return 0;

}

  • 33
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 28
    评论
冒泡排序和快速排序(qsort)虽然都是常见的排序算法,但它们的工作原理和效率有很大的不同。冒泡排序是一种简单的比较排序算法,而快速排序则是一种高效的分治策略。如果你想了解如何模仿`qsort`实现冒泡排序,其实这不是一个直接的对应,因为`qsort`是基于分治法的高效排序,而冒泡排序更适合教学和理解基本排序原理。 不过,为了满足你的要求,我们可以探讨一下如何用类似`qsort`的方式设计一个冒泡排序的“迭代”版本,虽然这并不是真正意义上的模仿,因为它们在实现上并不相同。 **冒泡排序的简化版(不是真正的`qsort`)**: 1. 定义一个辅助函数,类似于`qsort`的分区过程,但仅用于比较相邻元素并交换: ```c++ void bubbleSortPartition(int arr[], int low, int high) { while (low < high) { if (arr[low] > arr[high]) { std::swap(arr[low], arr[high]); } low++; high--; } } ``` 2. 用递归调用的方式实现冒泡排序: ```c++ void bubbleSortIterative(int arr[], int size) { for (int i = 0; i < size - 1; i++) { bubbleSortPartition(arr, 0, size - 1 - i); } } ``` 这里我们不是直接将整个数组作为一次排序,而是每次缩小待排序范围,直到整个序列有序。 **相关问题--:** 1. 冒泡排序与快速排序的主要区别是什么? 2. 在冒泡排序中,为什么要使用`bubbleSortPartition`函数? 3. 如何评价这种将冒泡排序与`qsort`风格结合的简化版本

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值