模拟实现qsort()

!!‧✧̣̥̇‧✦‧✧̣̥̇‧✦ ‧✧̣̥̇:Solitary-walk

      ⸝⋆   ━━━┓
     - 个性标签 - :来于“云”的“羽球人”。 Talk is cheap. Show me the code
┗━━━━━━━  ➴ ⷯ

本人座右铭 :   欲达高峰,必忍其痛;欲戴王冠,必承其重。

 


     希望在看完我的此篇博客后可以对你有帮助哟

  此外,希望各位大佬们在看完后,可以互赞互关一下,看到必回
    

时隔多日,重出江湖! 今日给大家 share  一个关于如何实现qsort()

目录


一· 前言

二.qsort()函数的介绍

三· 函数模拟实现

 模拟实现qsort()_第1张图片

首先想要实现此函数的模拟,我们就必须先了解qsort()

1.qsort()函数介绍

模拟实现qsort()_第2张图片

函数返回值:

 看不懂,木有关系,接下来我逐一解释

模拟实现qsort()_第3张图片

 

void qsort (
void* base, 
size_t num, 
size_t size,
int (*compar)(const void*,const void*)
);

第一个参数void* base:指向要比较首元素的地址,注意因为不知道要比较数据的类型,所以这里是void*

第二个参数:size_t num,所比较数组的元素 个数

第三个参数:size_t size 每个元素 所占字节的大小

第四个参数:int (*compar)(const void*,const void*)  是一个函数指针,这是用户自己设计的一个函数,用来比较元素大小

 2.qsort()的初步使用

用此函数实现对数据的快速排序

数组:int arr[ ] = { 2,3,1,6,5,4,7,8,9,10 };

 思路:我们用户需要自己写一个函数来实现元素比较大小的

注意此函数的返回类型必须是int

其次我们需要传入2个指针

函数的形参必须是:(const void* p1, const void* p2)

完整版代码:

#include
#include

int  cmp(const void* p1, const void* p2)
{
	return (*(int*)p1) - (*(int*)p2);//没有必要进行大小比较,直接做差即可
}
void Print(int arr[], int sz)
	{
	int i = 0;
	for(i = 0;i < sz;i++)
	{
		printf("%d ", arr[i]);
	}
}int main()
{
	int arr[] = { 2,3,1,6,5,4,7,8,9,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort( arr, sz, sizeof(int), cmp);
	//qsort()有4个参数:待排序数组首元素地址,待排序元素个数,每个元素的大小,函数的地址(函数指针)
	Print(arr, sz);
	return 0;
}
 3.模拟实现

这里我们借助冒泡排序的思想,来模拟实现

所以我们核心逻辑还是双层for循环

那么我们就需要考虑以下问题:

1)如何从指定的数据类型(int)来实现对任意数据类型的比较?

===》这里写成 void*

2)2相邻元素也不能直接进行比较,因为数据具体类型我们是未知的

===》这里我们借助函数指针来实现队任意数据类型比较

 注意对于void*类型指针不能直接解引用,也不能直接进行指针运算

这里我们强转成char*类型指针,可以一个字节一个字节进行比较

这里我们需要把下标为j所对应元素地址传过去:又因为每个数据所占字节我们已知:size

所以下标为 j 所对应元素地址:(char*)base + j * size

同上:下标为 j+1 所对应元素地址:(char*)base + (j+1) * size

void Qsort(void* base, int num, int size, int (*cmp)(const void* p1, const  void* p2))
{

	for (int i = 0; i < num-1; i++)//确定一共进行多少趟
	{
		//一趟排序 需要交换的对数
		for (int j = 0; j < num - 1 - i; j++)
		{
			//默认是按升序进行排列
			if (cmp((char*)base + j * size, (char*)base + (j + 1) * size ) > 0)//这里必须写上>0

			{
				//进行交换
				Swap((char*)base + j * size, (char*)base + (j + 1) * size, size);//在这里必须把要比较元素大小传过去
			}
		}
	}
}

 接下来就是如何实现2元素交换?

这里我们是一个字节一个字节来进行交换的

 模拟实现qsort()_第4张图片

 

void Swap(char* p1, char* p2, int size)
{
	//注意这里是一个字节一个字节进行交换
	/*
	char* tmp = NULL;
	for (int i = 0; i < size; i++)
	{
	      以下只是改变了指针的位置,并没有实现我数据 的交换,注意交换你本质是内容交换,所以需要先解引用
		tmp = p1;
		p1 = p2;
		p2 = tmp;
		p1++, p2++;
	}*/
	//正确代码
	char tmp = 0;
	for (int i = 0; i < size; i++)
	{
		tmp = *p1;
		*p1 = *p2;
		*p2 = tmp;
		p1++, p2++;
	}
	

}

 

 qsort()完整版代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include
//                                   以冒泡排序的思想模拟实现 qsort快速排序   注意这里用户需要根据自己需要写一个比较函数
//需要解决以下 问题:1) 实现对各种数据类型的模拟        2)对于2个元素的交换不仅仅是int类型数据    


void Swap(char* p1, char* p2, int size)
{
	//注意这里是一个字节一个字节进行交换
	/*
	char* tmp = NULL;
	for (int i = 0; i < size; i++)
	{
	      以下只是改变了指针的位置,并没有实现我数据 的交换,注意交换你本质是内容交换,所以需要先解引用
		tmp = p1;
		p1 = p2;
		p2 = tmp;
		p1++, p2++;
	}*/
	//正确代码
	char tmp = 0;
	for (int i = 0; i < size; i++)
	{
		tmp = *p1;
		*p1 = *p2;
		*p2 = tmp;
		p1++, p2++;
	}
	

}
void Qsort(void* base, int num, int size, int (*cmp)(const void* p1, const  void* p2))
{

	for (int i = 0; i < num-1; i++)//确定一共进行多少趟
	{
		//一趟排序 需要交换的对数
		for (int j = 0; j < num - 1 - i; j++)
		{
			//默认是按升序进行排列
			if (cmp((char*)base + j * size, (char*)base + (j + 1) * size ) > 0)//这里必须写上>0

			{
				//进行交换
				Swap((char*)base + j * size, (char*)base + (j + 1) * size, size);//在这里必须把要比较元素大小传过去
			}
		}
	}
}

int  cmp(const void*p1, const  void*p2)//用户自己设计的
{
	return (*(int*)p1) - (*(int*)p2);
}
void Print(int* p, int sz)
{
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", *p);
		p++;
	}
}
int main()
{
	int arr[] = { 7,4,1,2,5,8,3,6,9,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	Qsort(arr, sz, sizeof(arr[0]), cmp);
	Print(arr, sz);
  	return 0;
}

 运行结果:

 ok~~以上就是今日我要为各位老铁的分享,要是感觉还不错的话,点个赞,互关一下呗

你可能感兴趣的:(javascript,开发语言,ecmascript)