作者:~小明学编程
文章专栏:C语言基础知识
目之所及皆为回忆,心之所想皆为过往
今天给大家介绍C语言中一个比较好用的函数qsort函数以及我们模拟实现qsort函数的过程。
目录
qsort函数
作用
参数
用法
模拟实现qsort函数
这里是qsort函数的介绍,在这里简单的给大家翻译介绍一下
首先最上面说到它的作用,执行一个快速排序,qsort函数是一个排序函数,它的底层排序算法是快速排序。
void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *elem1, const void *elem2 ) );
接着就是它的返回值和参数,我们可以看到这长长的一串,看着就头疼,不过也没大家想象的那么复杂,给大家介绍一下大家就明白了。
首先看我们的第一个参数base,就是一个我们待排序的数组,接着就是num,顾名思义就是我们数组元素的的大小,待排序元素的个数,然后就是width参数,也就是我们待排元素中每个元素的大小,最后就是int (__cdecl *compare )(const void *elem1, const void *elem2 )这是一个回调函数,其中compare是一个函数指针,函数的两个参数分别是elem1和elem2(类型是void*)返回值是int类型,最后qsort的返回类型是void型。
下面就给大家介绍一下qsot函数的用法
//整数的比较
int cmp1(const void* e1, const void* e2)
{
return *((int*)e1) - *((int*)e2);
}
//测试整数
void test1()
{
int arr[5] = { 5,4,3,2,1 };
int sz = sizeof(arr) / sizeof(arr[0]);
my_qsort(arr, sz, sizeof(arr[0]), cmp1);
for (int i = 0; i < 5; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
test1();
return 0;
}
这个比较函数是需要我们自己去设计的,根据我们所比较的类型不同我们可以设计不同的比较函数
//浮点数的比较
int cmp2(const void* e1, const void* e2)
{
return *((double*)e1) - *((double*)e2);
}
//字符的比较
int cmp3(const void* e1, const void* e2)
{
return *((char*)e1) - *((char*)e2);
}
//字符串的比较
int cmp4(const void* e1, const void* e2)
{
return strcmp(*(char**)e1, *(char**)e2);
}
//结构体数字比较
int cmp5(const void* e1, const void* e2)
{
return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
//结构体字符串比较
int cmp6(const void* e1, const void* e2)
{
return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
下面是我们对一个整数数组的排序
//模拟实现qsort函数
void swap(char* ch1, char* ch2, int sz)
{
for (int i = 0; i < sz; i++)
{
char tem = *ch1;
*ch1 = *ch2;
*ch2 = tem;
ch1++;
ch2++;
}
}
void my_qsort(void* arr, int num, int size, int (*cmp)(const void* e1, const void* e2))
{
for (int i = 0; i < num; i++)
{
for (int j = 0; j < num - i - 1; j++)
{
//cmp((char*)arr + j * size, (char*)arr + (j + 1) * size)
if (cmp((char*)arr + j * size, (char*)arr + (j + 1) * size))
{
swap((char*)arr + j * size, (char*)arr + (j + 1) * size, size);
}
}
}
}
其中我们判断大小之后要进行一个交换,交换的过程我们采用的是逐个字节进行交换,也就是我们的swap函数所实现的功能。
下面是我们对各种类型的比较
#include
#include
#include
struct Stu
{
int age;
char name[20];
};
//整数的比较
int cmp1(const void* e1, const void* e2)
{
return *((int*)e1)-*((int*)e2);
}
//浮点数的比较
int cmp2(const void* e1, const void* e2)
{
return *((double*)e1) - *((double*)e2);
}
//字符的比较
int cmp3(const void* e1, const void* e2)
{
return *((char*)e1) - *((char*)e2);
}
//字符串的比较
int cmp4(const void* e1, const void* e2)
{
return strcmp(*(char**)e1, *(char**)e2);
}
//结构体数字比较
int cmp5(const void* e1, const void* e2)
{
return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
//结构体字符串比较
int cmp6(const void* e1, const void* e2)
{
return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
//模拟实现qsort函数
void swap(char* ch1, char* ch2, int sz)
{
for (int i = 0; i < sz; i++)
{
char tem = *ch1;
*ch1 = *ch2;
*ch2 = tem;
ch1++;
ch2++;
}
}
void my_qsort(void* arr, int num, int size, int (*cmp)(const void* e1, const void* e2))
{
for (int i = 0; i < num; i++)
{
for (int j = 0; j < num - i - 1; j++)
{
//cmp((char*)arr + j * size, (char*)arr + (j + 1) * size)
if (cmp((char*)arr + j * size, (char*)arr + (j + 1) * size))
{
swap((char*)arr + j * size, (char*)arr + (j + 1) * size, size);
}
}
}
}
//测试整数
void test1()
{
int arr[5] = { 5,4,3,2,1 };
int sz = sizeof(arr) / sizeof(arr[0]);
my_qsort(arr, sz, sizeof(arr[0]), cmp1);
for (int i = 0; i < 5; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
//测试浮点数
void test2()
{
double arr[5] = { 2.5,2.3,3.8,6.1,0.2 };
int sz = sizeof(arr) / sizeof(arr[0]);
my_qsort(arr, sz, sizeof(arr[0]), cmp2);
for (int i = 0; i < 5; i++)
{
printf("%.1lf ", arr[i]);
}
printf("\n");
}
//测试字符
void test3()
{
char arr[5] = { 'e','f','o','a','q' };
int sz = sizeof(arr) / sizeof(arr[0]);
my_qsort(arr, sz, sizeof(arr[0]), cmp3);
for (int i = 0; i < 5; i++)
{
printf("%c ", arr[i]);
}
printf("\n");
}
//测试字符串
void test4()
{
char* arr[] = { "shan","huani","ajfie","deygufefb" };
int sz = sizeof(arr) / sizeof(arr[0]);
my_qsort(arr, sz, sizeof(arr[0]), cmp4);
for (int i = 0; i < sz; i++)
{
printf("%s ", arr[i]);
}
printf("\n");
}
//测试结构体中的排序
void test5()
{
struct Stu arr[4] = { {11,"uheriu"},{37,"iuehen"},{8,"aouenioon"},{22,"ming"} };
int sz = sizeof(arr) / sizeof(arr[0]);
my_qsort(arr, sz, sizeof(arr[0]), cmp5);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i].age);
}
printf("\n");
my_qsort(arr, sz, sizeof(arr[0]), cmp6);
for (int i = 0; i < sz; i++)
{
printf("%s ", arr[i].name);
}
}
int main()
{
test1();
test2();
test3();
test4();
test5();
return 0;
}