快速排序qsort的用法及模拟实现
发布日期:2021-05-07 11:07:44 浏览次数:24 分类:精选文章

本文共 2683 字,大约阅读时间需要 8 分钟。

一.定义悉知:

1.1qsort是对指定的各元素进行无类型排序

在这里插入图片描述

1.2为什么是无类型排序呢

根据上图,c标准库的解释可以看到

1.2.1 void base:void可以接收任意类型

1.2.2 size_t :表示无符号整数,size_num表示需排序的元素个数

1.2.3 size:表示每个元素的大小;

1.2.4(compar)(const void,const void *):是一个函数指针,形参列表代表的是 待排序数据(内存块)序列中,任意一个元素的地址

二.使用方法

2.1一个函数要想实现排序那么它就得具备两种功能,一是进行函数之间的大小比较,另外一种是进行函数之间的位置交换;其中排序不需要类型,大小的比较需要类型,就将它交给外部函数进行大小比较。

2.2qsort是可以进行任意类型函数排序的,不同的类型函数之间的大小比较情况以及实现方式是不同的,如果都塞在qsort之中就会显得特别麻烦,因此有qsort就不提供数组大小比较的功能,这个功能由用户自己编写,再通过回调的方式获知信息,进行排序
*

三.使用实例

3.1进行数组的排序

代码如下

int  ComInt(const int *_x,const int *_y)//,传进来的是一个序列之中,任意一个元素的地址{   	int *x = (int*)_x;//void类型不能解引用	int *y = (int*)_y;	if (*x > *y)		return -1;	else if (*x < *y)		return 1;	else		return 0;}Print(int arr[],int num){   	for (int i = 0; i < num; i++)	{   		printf("%d\n", arr[i]);	}	printf("\n");}int main(){   	int arr[] = {    515, 11515, 544, 2322, 55, 886, 2, 58 };	int num = sizeof(arr) / sizeof(arr[0]);	Print(arr, num);	qsort(arr,num,sizeof(int),ComInt);	Print(arr, num);	system("pause");	return 0;}

3.2进行字符数组排序

int ComChar(const void *_x, const void *_y){   	char *x = *(char**)_x;//传进来的是指针数组的地址,因此是二级指针,	char *y = *(char**)_y;//需要的是字符串的地址,再解引用	return strcmp(x, y);}Prin(char *str[], int num){   	for(int i = 0; i < num; i++)	{   		printf("%s\n", str[i]);	}	printf("\n");}int main(){   	char *str[] = {    "a1231", "ab1353", "122", "f15" };	int num = sizeof(str) / sizeof(str[0]);	Prin(str, num);//打印没有交换之前的数组	qsort(str,num,sizeof(char*),ComChar);	Prin(str, num);//打印交换之后的数组排列	system("pause");	return 0;}

四.模拟实现qsort,进一步了解qsort

先上代码

void swap(void *_x, void *_y,size_t size){   	char *x = (char*)_x;//void*只是用来接收指针,但是类型不明确不能解引用;	char *y = (char*)_y;	char temp = 0;	while (size)//将每个字节的内容进行交换,一直到将整个元素大小size个字节交换完成为止	{   	    temp = *x;		*x = *y;		*y = temp;		x++;		y++;		size--;	}}int Comp(const void *_x,const void *_y)//传进来的是任意一个待排序元素的地址{   	int *x = (int *)_x;//void不能解引用	int *y = (int *)_y;	if (*x > *y)	{   		return 1;	}	else if (*x < *y)	{   		return -1;	}	else		return 0;}void MyQsort(void *arr, int num, size_t size,int (*Comp)(const void *, const void *)){   	assert(arr!= NULL);		assert(Comp != NULL);	char *e = (char *)arr;//void 类型不明确,对指针加减时无法判断步伐问题;	for (int i = 0; i < num - 1; i++)	{   		int flag = 0;		for (int j = 0; j < num - 1 - i; j++)		{   			if(Comp(e+j*size,e+(j+1)*size)>0)//arr强转成char后每次移动一个字节,所以需要乘上对应的元素大小size			{   				swap(e + j*size, e + (j + 1)*size,size);				flag = 1;			}		}		if (flag==0)		{   			break;//当没有进入冒泡循环时就停止;		}	}}int main(){   	int arr[] = {    343, 445, 4, 53, 32, 43, 5, 434, };	int num = sizeof(arr) / sizeof(arr[0]);	MyQsort(arr, num, sizeof(int),Comp);	Prin(arr, num);	return 0;}

由模拟实现的qsort可以清晰的认知,元素的交换排序不需要类型就可以进行,而元素之间的比较需要类型,因此这一部分由用户自我实现;

上一篇:scanf gets fgets的差别
下一篇:扫雷小游戏——简单易懂

发表评论

最新留言

不错!
[***.144.177.141]2025年04月14日 22时59分59秒