Implementation of C/C++ qsort function (bubble sort)

 Homepage:

There are still unknowns waiting to be explored_Data structure, small projects, C language difficulties-CSDN Blog

Topic columns:

C Language Difficulties_There are still unknown blogs waiting to be explored-CSDN Blog

Table of contents

I. Introduction

2. Explain the implementation

1. Sort the integer array 

 Sorting implementation

total code 

2. How to implement the parameter cmp function in qsort

1. Floating point type

2. Structure type 


I. Introduction

1. The first parameter is void*base: a pointer to the first object of the array to be sorted, converted to void*.

2. The second parameter is size_t num: the number of elements pointed to by the base in the array. size_t is an unsigned integer type.

3. The third parameter is size_t size: the size of each element in the array (in bytes). size_t is an unsigned integer type.

4. The fourth parameter is int (*compar)(const void*p1, const void*p2)): a pointer to a function that compares two elements.

Are you wondering why the parameters of the qsort function in the C language library function are so troublesome when we write bubble sort or selection sort? Why do we need to pass size_t size? Do you all have such questions? Today I will explain it to you in detail! (The qsort function in the library function is quick sort, and I use bubble sort to implement it) 

2. Explain the implementation

1. Sort the integer array 

 First, we need to design the parameters of the custom function first, but since we are implementing the qsort function in the library function, we can just write the parameters in the library function directly.

What we want to sort now is an integer array, so we also need an integer array.

sz is used to calculate the length of the array.

Question: Why is the parameter type of the custom function’s receiving array void* instead of int*?

Answer: void* is an untyped pointer that can point to any type of data without the need for forced type conversion. This means that when you pass the array arr to void*base, you can understand the void* type as a universal type regardless of why the type of base is not int*. (Note: Variables of type void* cannot be directly accessed by dereference, nor can pointer operations be performed. Forced type conversion is required to perform the above operations)

#include<stdio.h>
int cmp(void* x, void* y)
{
	return *(int*)x - *(int*)y;
}
//声明自定义排序函数
void qsort_m(void* base, size_t num, size_t size,int (*compar)(const void* p1, const void* p2));
int main()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1 };//提供一个整型数组
	int sz = sizeof(arr) / sizeof(arr[0]);//计算数组的长度
	qsort_m(arr, sz, sizeof(arr[0]), cmp);//自定义排序函数的调用
	int i = 0;
	for (i = 0; i < sz; i++)//输出
		printf("%d ", arr[i]);
	return 0;
}

 Sorting implementation

void qsort_m(void* base, size_t num, size_t size, int (*compar)(const void* p1, const void* p2))
{
	int i = 0, j = 0;
	for (int i = 0; i < num - 1; i++)
	{
		for (int j = 0; j < num - 1 - i; j++)
		{
			if (compar(((char*)base + j * size), (char*)base + (j + 1) * size) > 0)
			{
				//交换
				swap((char*)base + j * size, (char*)base + (j + 1) * size,size);
			}
		}
	}
}

compar(((char*)base + j * size), (char*)base + (j + 1) * size), this section needs to force the base to be converted to char* type, the purpose is that this char* can represent more For data types, char* dereference can only get one byte of data, while other types such as int* can get more bytes of data after dereferencing, which are larger than char*, so using the char* type can Get all the data passed in, so now you understand why you need to pass in the size of the data type. j*size is to allow the array to access the data in the next space.

 In the end, a relatively simple exchange function is left.

void swap(char* buf1, char* buf2, size_t size)
{
	int i = 0;
	for (int i = 0; i < size; i++)
	{
		int tmp;
		tmp = *(buf1 + i);
		*(buf1 + i) = *(buf2 + i);
		*(buf2 + i) = tmp;
	}
}

total code 

#include<stdio.h>
int cmp(void* x, void* y)
{
	return *(int*)x - *(int*)y;
}
void swap(char* buf1, char* buf2, size_t size);
void qsort_m(void* base, size_t num, size_t size, int (*compar)(const void* p1, const void* p2));
int main()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1 };//提供一个整型数组
	int sz = sizeof(arr) / sizeof(arr[0]);//计算数组的长度
	qsort_m(arr, sz, sizeof(arr[0]), cmp);//自定义排序函数的调用
	int i = 0;
	for (i = 0; i < sz; i++)//输出
		printf("%d ", arr[i]);
	return 0;
}
void qsort_m(void* base, size_t num, size_t size, int (*compar)(const void* p1, const void* p2))
{
	int i = 0, j = 0;
	for (int i = 0; i < num - 1; i++)
	{
		for (int j = 0; j < num - 1 - i; j++)
		{
			if (compar(((char*)base + j * size), (char*)base + (j + 1) * size) > 0)
			{
				//交换
				swap((char*)base + j * size, (char*)base + (j + 1) * size,size);
			}
		}
	}
}
void swap(char* buf1, char* buf2, size_t size)
{
	int i = 0;
	for (int i = 0; i < size; i++)
	{
		int tmp;
		tmp = *(buf1 + i);
		*(buf1 + i) = *(buf2 + i);
		*(buf2 + i) = tmp;
	}
}

2. How to implement the parameter cmp function in qsort

        cmp is a function pointer. This function pointer points to a function. The return value of this function is of type int. When the return value is <0, the element pointed by p1 precedes the element pointed by p2; when the return value is =0, the element pointed by p1 is equivalent to the element pointed by p2; when the return value is >0, the element pointed by p1 is after the element pointed by p2.

If you want to know in detail, please click on the link and read my previous article. 

Use of qsort function in C language_There are still unknown blogs waiting to be explored-CSDN Blog

1. Floating point type

int cmp(const void* p1, const void* p2)
{
	return *(float*)p1 - *(float*)p2;
}

2. Structure type 

typedef struct Stu
{
	char name[20];
	int score;
}Stu;
int cmp(const void* p1, const void* p2)
{
	return ((Stu*)p1)->score - ((Stu*)p2)->score;
}
int main()
{
	Stu s[3] = { { "张三",50 }, { "王五",70 }, { "李四",60 } };
	int sz = sizeof(s) / sizeof(s[0]);
	qsort(s, sz, sizeof(s[0]), cmp);
	for (int i = 0; i < sz; i++)
		printf("%s %d\n", s[i].name,s[i].score);
	return 0;
}

Finally, thank you for your support!

Guess you like

Origin blog.csdn.net/qq_73435980/article/details/133203433