[advanced pointer application (Simulated Implementation of qsort sorting function)]

Posted by epimeth on Mon, 21 Feb 2022 15:14:22 +0100


preface:
🐱 ‍ 🏍 Ha ha, I'm very glad that you have entered my series of articles on pointer learning. I believe that in the process of learning pointer, most of your little partners must not be plain sailing. Once you learn it, you know that there may be a stagnation in one of these links. I think so as a Xiaobai, but no matter what, you should not avoid learning, If you read my previous explanation on the basic knowledge of pointers, you will find that it is not difficult to simply understand pointers, which is mainly due to less practice. Today, we will use pointer knowledge to simulate the implementation of qsort sorting function.

Callback function

🐱 ‍ πŸ‘“ A callback function is a function called through a function pointer. If you pass the pointer of a function as a parameter to another function
Function. When this pointer is used to call the function it points to, we say it is a callback function. Callback function is not by
The implementer of this function is called directly, but by another party when a specific event or condition occurs, which is used to respond to the event or condition.

Introduction to qsort sorting function

🐱 ‍ πŸ‘“ Using the callback function to simulate the implementation of qsort (using bubbling method), we should first understand the function prototype of qsort
void qsort(voidbase,size_t num,size_twidth,int(_cdeclcompare)(constvoid*,const void*));
πŸ”Ž Explanation:
Void base: the address of the first element of the array to be sorted
size_t num: number of arrays to be sorted
size_t width: space occupied by each element of the array to be sorted (bytes)
int(_cdeclcompare)(const void,const void *): a function pointer. We can sort arrays, structures, strings, etc. through qsort function.

With the help of bubble sorting, the simulation of qsort function is completed

Bubble sorting function body

Easy to understand, I will call the function name I simulated and implemented as bubble

void bulble(void* base, int sz, int midth, int (*cmp)(void* e1, void* e2))
{
	int i, j;
	for (i = 0; i < sz - 1; i++)
	{
		for (j = 0; j < sz - i - 1; j++)
		{
			if (cmp((char*)base + j * midth, (char*)base + (j + 1) * midth) > 0)
			{
				swap((char*)base + j * midth, (char*)base + (j + 1) * midth, midth);
			}
		}
	}
}

🐱 ‍ πŸ‘“ According to the sorting rules of bubble sorting, sz-1 times will be sorted in total, and the adjacent elements of each time will be compared sz-i-1 times, so the logical idea is very clear
To realize the comparison of adjacent elements of different types of arrays, we need to think of a method to enable the comparison of adjacent elements of different data types, that is
To judge the size function cmp(); In order to enable different parameter types to be passed into the cmp() function, we can
Use void * type, and process the incoming adjacent element address with (char *) base + J * mid and (char *) base + (j + 1) * mid at the same time
Compare adjacent elements of different array types. For the same reason, when we judge the size of adjacent elements, we need to enter adjacent elements
For row exchange, we pass the address of adjacent elements into the adjacent element exchange function swap() in the same way;

Compare adjacent element size function cmp

🐱 ‍ πŸ‘“ First of all, for arrays with different data types, the comparison methods of the size functions of adjacent elements are different. Here are some examples

typedef struct stu//Define a structure type first
{
	char name[10];
	int year;
	double hight;
}stu;
int cmp_char(void* e1, void* e2)//Character type array comparison method function
{
	return(*(char*)e1 - *(char*)e2);//Because characters have ASCCL code value
}

int cmp_int(void* e1, void* e2)//Integer type array comparison method function
{
	return (*(int*)e1 - *(int*)e2);
}
int cmp_stu_name(void* e1, void* e2)//Struct character type member comparison method function
{
	return strcmp(((stu*)e1)->name, ((stu*)e2)->name);
}
int cmp_stu_year(void* e1, void* e2)Struct shaping type member comparison method function
{
	return ((stu*)e1)->year - ((stu*)e2)->year;
}

There are other kinds, so you can write by yourself

swap adjacent elements

🐱 ‍ πŸ‘“ Because the types of array elements passed in may be different when using the sorting function, a general exchange function should be used, that is, the
All bytes of the two incoming elements are exchanged, so that the two adjacent elements can be exchanged

Insert generation here void swap(char* bulf1, char* bulf2, int midth)
{
	char temp = 0;
	int i = midth;
	for (i = 0; i < midth; i++)
	{
		temp = *(bulf1);
		*(bulf1) = *(bulf2);
		*(bulf2) = temp;
		bulf1++;
		bulf2++;
	}
}Chip

Total code and effect of bubble function

Here is the code of the whole function and an array of partial detection function effects. You can have a look

#define  _CRT_SECURE_NO_WARNINGS
 Simulation Implementation of sorting library function void qsort(void*base,int num,int midth,int (*cmp)(void*e1,void*e2))
#include<stdio.h>
#include<string.h>
typedef struct stu
{
	char name[10];
	int year;
	double hight;
}stu;
void swap(char* bulf1, char* bulf2, int midth)
{
	char temp = 0;
	int i = midth;
	for (i = 0; i < midth; i++)
	{
		temp = *(bulf1);
		*(bulf1) = *(bulf2);
		*(bulf2) = temp;
		bulf1++;
		bulf2++;
	}
}

int cmp_char(void* e1, void* e2)
{
	return(*(char*)e1 - *(char*)e2);
}

int cmp_int(void* e1, void* e2)
{
	return (*(int*)e1 - *(int*)e2);
}
int cmp_stu_name(void* e1, void* e2)
{
	return strcmp(((stu*)e1)->name, ((stu*)e2)->name);
}
int cmp_stu_year(void* e1, void* e2)
{
	return ((stu*)e1)->year - ((stu*)e2)->year;
}
void bulble(void* base, int sz, int midth, int (*cmp)(void* e1, void* e2))
{
	int i, j;
	for (i = 0; i < sz - 1; i++)
	{
		for (j = 0; j < sz - i - 1; j++)
		{
			if (cmp((char*)base + j * midth, (char*)base + (j + 1) * midth) > 0)
			{
				swap((char*)base + j * midth, (char*)base + (j + 1) * midth, midth);
			}
		}
	}
}
void prin_char(char arr[4], int sz)
{
	int k = 0;
	for (k = 0; k < sz; k++)
	{
		printf("%c ", arr[k]);
	}
	printf("\n");
}
void prin_int(int arr[4], int sz)
{
	int k = 0;
	for (k = 0; k < sz; k++)
	{
		printf("%d ", arr[k]);
	}
	printf("\n");
}
void prin_stu_name(stu arr_stu[], int sz)
{
	int i = 0;
	printf("%s\n", "Sort by name as follows");
	for (i = 0; i < sz; i++)
	{
		printf("%-s\t", arr_stu[i].name);
		printf("%-d\t ", arr_stu[i].year);
		printf("%-f\t ", arr_stu[i].hight);
		printf("\n");
	}
}
void prin_stu_year(stu arr_stu[], int sz)
{
	int i = 0;
	printf("%s\n", "Sort by age as follows");
	for (i = 0; i < sz; i++)
	{
		printf("%-s\t", arr_stu[i].name);
		printf("%-d\t ", arr_stu[i].year);
		printf("%-f\t ", arr_stu[i].hight);
		printf("\n");
	}
}

void test1()//Total function for sorting and printing character array
{
	char arr[4] = { 'd','k','h','w' };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int midth = sizeof(arr[0]);
	bulble(arr, sz, midth, cmp_char);
	prin_char(arr, sz);
}
void test2()//Integer array sort print total function
{
	int arr[10] = { 1,3,2,4,5,7,6,9,8,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int midth = sizeof(arr[0]);
	bulble(arr, sz, midth, cmp_int);
	prin_int(arr, sz);
}
void test3()//Structure array member printing
{
	stu arr_stu[3] = { { "liqin",40,160.1},{"zhuyang",51,150.2},{"pangge",22,148.2} };
	int sz = sizeof(arr_stu) / sizeof(arr_stu[0]);
	int midth = sizeof(arr_stu[0]);
	bulble(arr_stu, sz, midth, cmp_stu_name);
	prin_stu_name(arr_stu, sz);
	bulble(arr_stu, sz, midth, cmp_stu_year);
	prin_stu_year(arr_stu, sz);

}
int main()
{
	test1();
	test2();
	test3();
	return 0;
}


Huhuhuhuhu~~
It's over. Just bite your teeth

Bao, give me a third company 😍😍😍😍😍

Topics: C Algorithm pointer