我们今天来认识一下C语言中的库函数qsort函数
void*类型介绍
通过一段代码来介绍:
int main() {
int a = 10;
char* pa = &a;//int*,编译器会报警告
void* pv = &a;//编译器不会报警告
//void* 是无具体类型的指针,可以接受任意类型的地址
//void*是无具体类型的指针,所以不能解引用操作,也不能±整数
return 0;
}
qsort介绍
qsort 这个函数可以排序任意类型的数据
首先使用人家的函数,就要引头文件 # include <stdlib.h>
其次,明白每一个函数参数的意义
这里的compare函数(简化为cmp)需要写成什么样的?
下面是函数的格式
这里我们来解释一下函数各个参数的意义
void qsort(void* base,//你要排序的数据的起始位置
size_t num,//待排序的数据元素的个数
size_t width,//待排序的数据元素的大小(单位是字节)
int(* cmp)(const void* e1, const void* e2)//函数指针-比较函数
);
比较2个整型元素
e1指向一个整数
e2指向另外一个整数
利用qsort排序一个整型数组
下面是qsort函数的具体使用方法。
qosrt函数的使用者得实现一个比较函数
#include <stdio.h>
#include<stdlib.h>
int int_cmp(const void * p1, const void * p2)
{
return (*( int *)p1 - *(int *) p2);//参照上图
}
int main()
{
int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
int i = 0;
qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof (int), int_cmp);
for (i = 0; i< sizeof(arr) / sizeof(arr[0]); i++)
{
printf( "%d ", arr[i]);
}
printf("\n");
return 0;
}
利用qsort排序一个结构体
int cmp_stu_by_name(const void* e1, const void* e2)
{
//strcmp --> >0 ==0 <0
return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
int cmp_stu_by_age(const void* e1, const void* e2)
{
return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
void test2()
{
//测试使用qsort来排序结构数据
struct Stu s[] = { {"zhangsan", 15}, {"lisi", 30}, {"wangwu", 25} };
int sz = sizeof(s) / sizeof(s[0]);
//qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);
}
void test4()
{
//测试使用qsort来排序结构体里的数据
struct Stu s[] = { {"zhangsan", 15}, {"lisi", 30}, {"wangwu", 25} };
int sz = sizeof(s) / sizeof(s[0]);
bubble_sort(s, sz, sizeof(s[0]), cmp_stu_by_name);
//bubble_sort(s, sz, sizeof(s[0]), cmp_stu_by_age);
}
int main()
{
test2();
test3();
return 0;
}
如何自己实现一个qsort排序(基于冒泡排序)
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 sz,
int width,
int(*cmp)(const void* e1, const void* e2))
{
int i = 0;
//趟数
for (i = 0; i < sz - 1; i++)
{
int flag = 1;
//自定义一个标签,若这个标签一趟冒泡排序最后还是1,则这个序列已经有序,不用再进行第二趟了
//一趟冒泡排序的过程
int j = 0;
for (j = 0; j < sz - 1 - i; j++)
{
if (cmp((char*)base + j * width,
(char*)base + (j + 1) * width) > 0)
//cmp的两个参数是待比较的两个元素的地址
{
//交换
Swap((char*)base + j * width,
(char*)base + (j + 1) * width, width);
flag = 0;
}
}
if (flag == 1)
{
break;
}
}
}
int int_cmp(const void* p1, const void* p2)
{
return (*(int*)p1 - *(int*)p2);
}
#include<stdio.h>
int main()
{
int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz, sizeof(arr[0]), int_cmp);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}