前言:
之前介绍了指针的一些内容,也学习了冒泡排序的方法,但是冒泡排序仅针对整形来排序,并且每次还需要手写,有没有一个函数,既可以排任意类型的数据,又能直接调用,它就是---qsort函数。
gogogo
目录:
1.什么是qsort函数
2.qsort函数怎么用
3.qsort和冒泡排序的对比
正文:
1.什么是qsort函数
qsort
是 C 语言标准库中的一个快速排序函数,它位于stdlib.h
头文件中。它的返回值类型是void
,因为qsort
函数直接对传入的数组进行排序,不会返回排序后的数组。
我们可以通过cplusplus这个网站查看库函数(qsort)的函数参数类型:
qsort函数有四个参数:
1.void* base:它指向要排序函数的第一个数组元素的指针。(因为不知道要排序的是什么类型,参数为(void*))。
2.size_t num:它是要排序数组的元素个数。可以用sizeof(数组名)/sizeof(第一个元素)求出。返回类型是size_t类型,因为元素个数不可能为负。
3.size_t size:它是要排序的一个元素字节大小。可以用sizeof(第一个元素)求出。
4.int*(cmp)(const void*,const void*):它是一个函数指针,指向一个比较函数,该比较函数比较两个元素的大小。
2.qsort函数怎么用
好,上面看不懂你先别慌,我们知道了qsort函数的参数类型,现在我们来解锁一下qsort函数的用法,你就会啦~
想要完成qsort函数,我们使用者必须提供一个函数接口(cmpareMyType),这个函数接口就是我们想比较的数据类型的两个数据,想要比较整形,就比较整形的两个数据的大小,想要比较结构体,就比较结构体的两个数据的大小。那么有一个规则:我们可以参考
也就是,如果第一个数<第二个数,返回-1;第一个数等于第二个数,返回0 ;第一个数>第二个数,返回1
我们现在来完成(cmpareMyType)这个函数来比较整形:
int cmp_int(const void* e1, const void* e2)
{
if (*(int*)e1 > *(int*)e2)
return 1;
else if ((*(int*)e1 < *(int*)e2))
return -1;
else
return 0;
}
当然:这种写法显然很冗余了,我们还可以这样写:
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
到这里,你已经成功了80%了,下面我们就根据它的规则套模版就行了。
qsort排序整形:
再说一遍规则:我们把我们要排序的数组按qsort函数的参数一一传给它,然后我们再自已实现一个要比较的数据类型的函数就搞定了(上面已经实现啦):
不要忘记头文件(<stdlib.h>)
#include <stdio.h>
#include <stdlib.h>
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
int main()
{
int arr[] = { 2,5,1,7,9,6,4,8,10,3 };//无序数组
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_int);//qsort排序整形
//打印
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
是不是很神奇,我们什么也没干,qsort函数就帮我们排序好了。接着我们再试一下qsort函数排序字符型,结构体类型。
qsort排序字符型:
#include <stdio.h>
#include <stdlib.h>
int cmp_char(const void* e1, const void* e2)
{
return *(char*)e1 - *(char*)e2;
}
int main()
{
char str[] = {'a','s','b','e','h','g','\0'};//无序数组
int sz = sizeof(str) / sizeof(str[0]);
qsort(str, sz, sizeof(str[0]), cmp_char);//qsort排序字符形
//打印
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%c ", str[i]);
}
return 0;
}
qsort排序结构体类型
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Stu
{
int age;
char name[10];
};
//e1指向一个结构体对象,e2指向一个结构体对象
int cmp_name(const void* e1, const void* e2)
{
return strcmp( ((struct Stu*)e1)->name , ((struct Stu*)e2)->name);//结构体指针->成员
}
int main()
{
struct Stu s[] = { {19,"zhangsan"},{17,"lisi"},{30,"wangwu"} };//结构体无序数组
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]), cmp_name);//qsort排序结构体
//打印
int i = 0;
for (i = 0; i < sz; i++)
{
printf("name:%s\n", s[i].name);
}
return 0;
}
哎,确实很神奇,只需要任意数据类型数组中的两个元素,就能排序整个数组。
4.qsort和冒泡排序的对比
我们可以对比一下冒泡排序和qsort函数排序整形
下面是冒泡排序的排序方式:
void bubble_sort(int arr[], int sz)//参数接收数组元素个数
{
int i = 0;
for (i = 0; i < sz - 1; i++)
{
int flag = 1;//假设这⼀趟已经有序了
int j = 0;
for (j = 0; j < sz - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
flag = 0;//发⽣交换就说明,⽆序
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
if (flag == 1)//这⼀趟没交换就说明已经有序,后续⽆序排序了
break;
}
}
int main()
{
int arr[] = { 3,1,7,5,8,9,0,2,4,6 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
我们很显然能发现,qsort函数比起冒泡排序使用起来方便快捷,但是我们并不能忘掉冒泡排序的思想。为了有耐心学下去,我把qsort函数的模拟实现放到了下一篇,希望大家一定要学会qsort函数的使用。好啦~欲知后事如何,请看下篇分解~