前言
之前有篇文章讲过C语言冒泡排序的思想,给定一个整型数组,对其进行升序或降序排列,但是有一定的局限性,只能排序整型的数组,对于字符数组、浮点型数组、结构体的一些排序无法实现。(对冒泡排序还不是很了解的,可点击链接跳转C语言——冒泡排序)
qsort函数
在C语言的库函数中,有一个排序函数——qsort。
文本定义:(下面逐一讲解)
底层思想:
qsort函数的排序思想是——快速排序。
头文件:
<stdlib.h>
函数参数:
这里的compare函数是需要自己写的,因为需要比较什么类型是有本人指定。
qsort函数的使用
整型比较:
#include<stdio.h>
#include<stdlib.h>
int cmp(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
int main()
{
int arr[10] = { 2,4,1,4,6,8,9,12,21,17 };
int i = 0;
qsort(arr, 10, 4, cmp);
return 0;
}
字符比较:
#include<string.h>
int cmp_char(const void* e1, const void* e2)
{
return strcmp((const char*)e1, (const char*)e2);
}
int main()
{
char arr[10] = { 'a','g','q','f','z','s','i','p','e','j' };
qsort(arr, 10, 1, cmp_char);
return 0;
}
结构体比较:
typedef struct
{
char name[10];
int age;
}Stu;
int cmp_stu_age(const void*e1,const void*e2)
{
return ((Stu*)e1)->age - ((Stu*)e2)->age;
}
int cmp_stu_name(const void* e1, const void* e2)
{
return strcmp(((Stu*)e1)->name, ((Stu*)e2)->name);
}
int main()
{
Stu s[3] = { {"lihua",20},{"wangwei",12},{"baby",25} };
//年龄比较
qsort(s, 3, sizeof(s[0]), cmp_stu_age);
//名字比较
qsort(s, 3, sizeof(s[0]), cmp_stu_name);
return 0;
}
qsort模拟实现(冒泡排序思想)
typedef struct
{
char name[10];
int age;
}Stu;
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
int cmp_stu_age(const void*e1,const void*e2)
{
return ((Stu*)e1)->age - ((Stu*)e2)->age;
}
int cmp_stu_name(const void* e1, const void* e2)
{
return strcmp(((Stu*)e1)->name, ((Stu*)e2)->name);
}
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,size_t num,size_t width,int (*cmp)(const void*e1,const void*e2))
{
size_t i = 0;
for (i = 0; i < num-1; i++)
{
size_t 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 test1()
{
int arr[10] = { 2,4,6,1,2,11,10,3,21,10 };
bubble_sort(arr, (sizeof(arr) / sizeof(arr[0])), sizeof(arr[0]), cmp_int);
}
void test2()
{
Stu s[3] = { {"lihua",20},{"wangwei",12},{"baby",25} };
//年龄比较
bubble_sort(s, sizeof(s)/sizeof(s[0]), sizeof(s[0]), cmp_stu_age);
//名字比较
bubble_sort(s, sizeof(s) / sizeof(s[0]), sizeof(s[0]), cmp_stu_name);
}
int main()
{
test1();
test2();
return 0;
}
在比较的时候没有把参数的类型写死,所以将地址强制类型转换成char*类型,然后在加上所需偏移的字节即可访问到我们所需比较的元素。
在进行元素交换的时候也是同理,不知道元素的类型,所以我们一个字节一个字节的进行交换。
结语
qsort函数是C语言库里面实现快速排序的算法,另外qsort是属于一个回调函数的一个典型例子(文章链接:内含回调函数概念)。