qsort函数的介绍
qsort(即quick sort)是C语言中的一个标准库函数,用于对数组进行快速排序。它是一种高效的排序算法,具有较好的平均和最坏情况下的时间复杂度。
qsort函数的声明如下:
void qsort(void* base, size_t nmemb, size_t size, int (compar)(const void, const void*));
参数解释如下:
base:指向要排序的数组的第一个元素的指针。
nmemb:数组中元素的数量。
size:每个元素的大小(以字节为单位)。
compar:指向比较函数的指针,用于定义元素之间的排序顺序。
比较函数compar用于定义元素之间的排序顺序,它接收两个指向元素的指针,通常为 void* 类型。比较函数需要返回一个整数值,代表两个元素的大小关系:
如果返回值小于0,表示第一个元素应该排在第二个元素之前。
如果返回值等于0,表示两个元素相等。
如果返回值大于0,表示第一个元素应该排在第二个元素之后。
使用qsort函数,可以对各种类型的数组进行排序,包括整型、浮点型、字符型以及自定义结构体等。
整形排序
我们刚刚了解到了,对于排序不同类型的数据,需要自定义不同的compar函数,接下来看一下整形的例子
#include <stdio.h> #include <stdlib.h> // 比较函数,用于升序排序 int compare(const void* a, const void* b) { return (*(int*)a - *(int*)b); } int main() { int arr[] = {5, 2, 8, 1, 9, 3}; int size = sizeof(arr) / sizeof(arr[0]); qsort(arr, size, sizeof(int), compare); printf("升序排序结果:"); for (int i = 0; i < size; i++) { printf("%d ", arr[i]); } printf("\n"); return 0; }
运行程序如下:
接下来就直接只展示不同类型的数据compare函数
浮点型排序
int cmp_float(const void* e1, const void* e2) { return (int)(*(float*)e1 - *(float*)e2); }
字符串排序
int cmp_str_size(const void* e1, const void* e2) { return strcmp((char*)e1, (char*)e2); }
结构体排序
int cmp_by_name(const void* e1, const void* e2) { return (int)(((stu*)e1)->age - ((str*)e2)->age); }
结构体中文名字排序示例
上述结构体排序是年龄,接下来我们来比较结构体中按中文名字排序
#include <stdio.h> #include <stdlib.h>//使用qsort函数需要包含头文件 #include <string.h> struct stu { char name[20]; int age; }; int cmp_name(const void* e1, const void* e2) { return strcmp(((struct stu*)e1)->name , ((struct stu*)e2)->name); } int main() { struct stu arr[3] = { {"张三", 20}, {"李四", 18}, {"王五", 36} }; int sz = sizeof(arr) / sizeof(arr[0]); qsort(arr, sz, sizeof(arr[0]), cmp_name); for (int i = 0; i < sz; i++) { printf("%s %d ", arr[i].name, arr[i].age); printf("\n"); } return 0; }
qsort函数的模拟
了解了qsort函数的使用,我们来尝试模拟一下qsort函数的实现
#include<stdio.h> void swap(char* p1, char* p2, int width) { for (int i = 0; i < width; i++) //不知道是什么类型,所以要一个字节一个字节来进行交换 { char temp = *p1; *p1 = *p2; *p2 = temp; p1++; p2++; } } int compare(const void* p1, const void* p2) { return *((int*)p1) - *((int*)p2); } //void* base - 要求排序不同类型的数组,void*恰好能接收任意类型的数据 //int num - 元素个数 //int width - 一个元素的大小 //int (*compare)(const void* p1, const void* p2) 函数传参函数指针接收 int my_qsort(void* base, int num, int width,int (*compare)(const void* p1, const void* p2))) { for (int i = 0; i < num - 1; i++) { for (int j = 0; j < num - 1 - i; j++) { //强制类型转化为char*型的数据,是因为一开始不知道数组的类型 //如果要访问数据的话,只能一个字节一个字节的访问 //这样有利于排序各种类型的数 if (compare((char*)base + j * width,(char*)base + (j + 1) * width) > 0) { //写一个Swap函数来交换 swap((char*)base + j * width, (char*)base + (j + 1) * width, width); } } } } int print(int arr[], int num) { for (int i = 0; i < num; i++) { printf("%d ", arr[i]); } } int main() { int arr[10] = { ![11,23,54,65,87,34,59,55,66,44] int num = sizeof(arr) / sizeof(arr[0]);//计算数组中的元素个数 //打印排序前的数组 printf("排序前为:"); print(arr, num); printf("\n"); my_qsort(arr, num, sizeof(arr[0]), compare); //打印排序后的数组 printf("排序后为:"); print(arr, num); return 0; }
运行结果如下:
内容就分享到这里,各位看客老爷万福金安。