qsort函数的使用
一.qsort函数的使用:
qsort 函数是C语言标准库中的一个函数,用于对数组或其他可迭代数据结构中的元素进行快速排序(Quick Sort)。它允许你对一组数据按照自定义的比较函数进行排序,以实现升序或降序排列。
void qsort(void *base, size_t num, size_t size, int (*compar)(const void *, const void *));
其中,最以上参数说明如下:
base:要排序的数组或数据结构的首地址。
num:数据结构中元素的数量。
size:每个元素的大小(以字节为单位)。
compar:一个用于比较两个元素的函数指针,该函数必须返回一个整数值,表示两个元素的相对顺序。函数的原型为 int compar(const void *p1, const void *p2),其中 *p1和 *p2 分别是指向待比较元素的指针。
当p1>p2 返回小于0的数
当p1=p2返回0
当p1<p2返回大于0的数
qsort 函数使用快速排序算法,它是一种高效的排序算法,平均情况下的时间复杂度为 O(n log n),其中 n 是元素的数量。排序的结果将反映在传入的 base 参数所指向的数组或数据结构中
注意:
在C语言中,函数指针允许你将函数作为参数传递给其他函数。在这种情况下,qsort 函数需要一个用于比较两个元素的函数,即使用compare函数,但是由于它不知道如何比较具体的数据类型,因此它接受一个通用的函数指针,这个函数指针可以指向各种不同的比较函数。
下面是对函数指针 int (*compar)(const void *, const void *) 的解释:
int:指定了这个函数指针所指向的函数应该返回一个整数值。这个整数值用于表示两个元素的相对顺序。
(*compar):这表示 compar 是一个函数指针,可以调用函数。
(const void *, const void *):这是指定函数参数的部分。compar 函数应该接受两个指向常量 void 类型的指针作为参数,这两个指针通常用于表示要比较的元素。这里使用 const void * 类型是因为 qsort 不知道要排序的数据的具体类型,因此它将这些数据视为通用的字节序列。
在 qsort 函数内部,void base 参数表示待排序数组的首个元素地址。具体来说,它是指向待排序数组的指针。qsort 函数通过这个指针来访问整个数组的元素。此指针的类型是 void,这意味着它能够指向任何类型的数据,这也解释了为什么 qsort 函数被称为通用排序函数,可以用于对不同类型的数据进行排序。
.以下是对qsort函数的基本演示:
#include<stdio.h>
#include<stdlib.h>
int compare(const void* p1, const void* p2)
{
return (*(int*)p1 - *(int*)p2);
}
int main()
{
int arr[] = { 10,20,30,40,50,60 };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), compare);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
二.qsort函数的使用:
1.qsort函数对整数数组的排序:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
//sqort函数对整型数组的排序
int compare(const void* p1,const void* p2)
{
return (*(int*)p1 - *(int*)p2);
}
int main()
{
int arr[] = { 1,2,32,42,12,43,23,54,77,13,27,8,99,0 };
int num = sizeof(arr) / sizeof(arr[0]);
int size = sizeof(arr[0]);
qsort(arr, num, size, compare);
for (int i = 0; i < num; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
2.qsort函数对结构体的排序
//qsort函数对结构体的排序
struct Stu {
int age;
char name[20];
};
int cmp_stu_by_age(const void* elem1,const void* elem2)
{
return ((struct Stu*)elem1)->age - ((struct Stu*)elem2)->age;
}
int main()
{
struct Stu arr[] = { {22,"zhangsan"},{21,"lisi"},{20,"wangwu"} };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_age);
return 0;
}
则排序后为:
三.模拟实现qsort函数
使用冒泡的思路来实现qsort函数:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int cmp(const void* elem1, const void* elem2)
{
return (*(int*)elem1 - *(int*)elem2);
}
void Swap(char* buf1, char* buf2, int width)
{
int i = 0;
for (i = 0; i < width; i++)
{
char tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
void bubble_sort(void* base, int num, int width, int(*cmp)(const void* elem1, const void* elem2))
{
//计算行
int i = 0;
for (i = 0; i < num - 1; i++) //计算冒泡排序的趟数
{
//计算列
int j = 0;
for (j = 0; j < num - 1 - i; j++)
{
//排序为降序
if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
{
//交换
Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
}
}
}
}
void print_sort(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
void test2()
{
int arr[] = { 9,8,7,6,5,4,3,2,1 };
//排序为升序
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz, sizeof(arr[0]), cmp);
print_sort(arr, sz);
}
int main()
{
test2();
return 0;
}