Detailed explanation of qsort function (the magic soldier in the C language sorting world)

No matter how bitter the road ahead is, as long as you walk in the right direction, no matter how rough it is, you will be closer to happiness than standing still 

Table of contents


  Hello everyone, I am Ji Ning. 

  This article will bring you a very powerful function that can quickly solve most of the sorting problems you encounter. Before learning data structures and algorithms, this function is the god of sorting!

1. Detailed explanation and usage of qsort function  

  If you have not learned the data structure and only use bubble sort, then you must learn the qsort quick sort function.

  The most comfortable thing about the qsort function for users is that it can sort data of any data type, and there is no need for the user to write an algorithm to achieve the sorting. The screenshot below is from the official website of the qsort function (qsort quick sort function official website: qsort )

  The qsort function has 4 parameters in total, the first parameter base is the first address of the collection to be sorted; the second parameter num is the total number of elements of the data to be sorted; the third parameter size is each element of the collection to be sorted The size of the occupied memory space; the fourth parameter is a function pointer (int(*)(const void*, const void*)) . The fourth parameter needs to be implemented by the user, but it is also very simple. You only need to determine the data type of the elements to be compared, and then use the appropriate method to compare the data size to return a signed integer.

  Because the return type of the function pointer in qsort is int, and both parameters are const void*; secondly, the function of the comper function is to realize the comparison of two data types, so the function can be designed in the following way

int Comper(const void* p1, const void* p2)
{
	;//需要将传进来的p1、p2进行比较 
}

  Use p1 and p2 to accept, but considering that both p1 and p2 are pointers of void* type, and pointers of void* type cannot be dereferenced, so when making comparisons, the forced types of p1 and p2 must be converted into corresponding Compare the pointers of the data types, and then dereference them for comparison. Here are a few examples of different data types

int Comper(const void* p1, const void* p2)
{
	return (*(int*)p1) - (*(int*)p2);//整型数据
}
int Comper(const void* p1, const void* p2)
{
	return strcmp((*(char*)p1), (*(char*)p2));//字符型数据
}
int Comper(const void* p1, const void* p2)
{
	return (*(float*)p1) - (*(float*)p2);//浮点型数据
}
int Cmpper(const void* p1, const void* p2)
{
	return (((struct Stu*)p1)->age - ((struct Stu*)p2)->age);//结构体类型,成员为整形
}
int Cmpper(const void* p1, const void* p2)
{
	return  strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);//结构体类型,成员为字符串
}

  After using the qsort function in the code, and then design a very simple comparison function, the compiler will automatically sort the data. Of course, if you want to sort the data set in descending order, you only need to exchange the positions of p2 and p1 in the Comper function That's it, are you eager to try, isn't this easier than writing dozens of lines of code to sort?

Second, realize the qsort function

  We are the first to contact, and the most used one is the bubble sorting algorithm , then we use bubble sorting to implement an identical qsort function, but it may be slightly insufficient in time complexity. Everyone is concerned about the time complexity of bubble sorting , haha, I understand everything.

  Use the bubble sorting algorithm to realize the qsort function. The idea of ​​bubble sorting is that small numbers bubble and large numbers settle. But in fact, one of the biggest problems is how to achieve the comparison and exchange of different data types in the comparison part of the bubble sort. For this, we can take advantage of the fact that the parameter passed by it is a null pointer: force the null pointer The type is converted into a pointer of the data type of the data to be compared, and the converted pointer is first dereferenced to compare the size, and then the content is exchanged byte by byte (just add a loop in the exchange part of the bubble sort).

void my_qsort(void* base, size_t Num, size_t Size, int(*Com)(const void*, const void*))//首元素地址  元素个数  每个元素的字节数  Com比较函数
{
	int i = 0;
	for (i = 0; i < Num - 1; i++)//循环的趟数
	{
		int j = 0;
		for (j = 0; j < Num - 1 - i; j++)//每趟循环要比较的次数
		{
			//实现比较、交换
			if (Com((char*)base + Size * j, (char*)base + Size * (j + 1)) > 0)
			{
				//交换---逐个字节交换n   
				int z = 0;
				for (z = 0; z < Size; z++)
				{
					char tmp = 0;
					tmp = *((char*)base + Size * j + z);
					*((char*)base + Size * j + z) = *((char*)base + Size * (j + 1) + z);
					*((char*)base + Size * (j + 1) + z) = tmp;
				}
			}
		}
	}
}
int Comper(const void* p1, const void* p2)
{
	return (*((int*)p1) - *((int*)p2));
}
int main()
{
	//测试my_qsort函数
	int arr[10] = { 4,3,5,6,7,8,9,10,2,1 };
	my_qsort(arr, 10, 4, Comper);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

  After the comparison and exchange part is implemented, the my_qsort function can be used as the qsort function. 

insert image description here

  The blogger has been writing for a long time, if you can give the blogger a free triple combo to encourage the blogger, then I think your Thai pants are really spicy! ! !

Guess you like

Origin blog.csdn.net/zyb___/article/details/131837696