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

发布于:2023-01-19 ⋅ 阅读:(456) ⋅ 点赞:(0)

作者:~小明学编程

文章专栏: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;

}

本文含有隐藏内容,请 开通VIP 后查看