hello大家好,我是c语言boom家宝,今天为大家分享的博客内容是qsort快速排序,简称快排的一个知识点的讲解。
在讲到快排之前,允许博主先提一嘴冒泡排序。大家在c语言的学习过程中,冒泡排序是必不可少会学习到的一个思想,那么冒泡排序是怎么样的呢?我们看代码:
int main() {
int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
int i = 0;
int sz = sizeof(arr) / sizeof(int);
for (i = 0; i < sz - 1; i++) { //一共要交换多少次数
int j = 0;
for (j = 0; j < sz - 1 - i; j++) { //每一次交换的元素个数
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
for (i = 0; i < sz; i++) {
printf("%d ", arr[i]);
}
return 0;
}
这样就完成一个冒泡排序啦,非常的简单。但是冒泡排序简单是简单,可是效率十分的低。它通过重复很多次的挨个比较,然后交换的方式达成最后的排序效果。如果数组内容非常非常的多呢?那么排序所用的时间将会非常的多。其次,上面的这个冒泡排序只适用于排序整型。如果我又需要对其他类型的数据排序,如浮点型,字符型等,那么就需要重新写一个冒泡排序的代码,十分的复杂。基于这几点原因,所以博主将讲解一下qsort快速排序的使用:
库函数qsort,快排,适用于任何类型数据的排序。使用时需要引用<stdlib.h>头文件
博主在官网上查询qsort的使用方法,它们是这样介绍的:如图
我们再来看一下使用qsort库函数需要调用的参数是什么
那么qsort函数的返回值是什么,如图:
也就是说如果p1指向的元素值小于p2指向的元素值,返回一个小于0的数。反之,返回一个大于0的数。如果相等,则返回0.
总结一下,当我们要使用qsort库函数的时候,需要传的参数如下。他们各自表示的意思也有打在备注里面,方便大家理解。如果不知道什么是函数指针,请移步链接:http://t.csdn.cn/FtRCn,博主有在里面对函数指针进行讲解,这很重要,因为要想使用qsort库函数,必须要创建一个函数指针才可以。
void qsort(void* base, //指向了需要排序的数组的第一个元素
size_t num, //排序的元素个数
size_t size, //一个元素的大小,单位是字节
int (*cmp)(const void*,const void*) //函数指针类型,
//这个函数指针指向的函数,需要能够比较base指向数组中的两个元素
);
细心的阅读朋友会发现,这个函数指针的参数部分类型是const void*类型。而void*这个类型有一些特殊,void*不能直接进行解引用操作,也不能直接进行指针的运算。但是,void*指针是无具体类型的指针,它可以接收任意类型的地址。这一点就十分妙哉,因为我们在使用函数过程中并不会提前知道你具体会传过来什么类型的参数。如果还像上面冒泡排序一样,那么就写死了,就只能完成一个类型数据的排序。 既然不能直接解引用,那我们就可以在使用的时候把它强制转换成我们需要的类型。具体实现如下:
#include <stdio.h>
#include <stdlib.h>
int cmp_int(const void* p1, const void* p2) {
return(*(int*)p1 - *(int*)p2);
}
void test1() {
int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
int sz = sizeof(arr) / sizeof(int);
//qsort默认排的是升序
qsort(arr, sz, sizeof(arr[0]), cmp_int);
int i = 0;
for (i = 0; i < 10; i++) {
printf("%d ", arr[i]);
}
}
int main() {
test1();
return 0;
}
qsort默认是排成升序,如果想排成降序,我们只需要把上述代码中的return(*(int*)p1 - *(int*)p2);改成return(*(int*)p2 - *(int*)p1);就可以了。上述代码编译结果如下:
当然,前面也说到过,qsort可以排序任何一个类型的。博主这里再举例用qsort来排序结构体又是怎么排序的呢?代码如图
我们只需要按照格式去传参数,然后写一个函数指针就可以了。qsort有着十分高效的效率,各位阅读朋友可以自己尝试一下去写一个快排出来