上一篇的冒泡排序讲到,有这么一个函数,它可以排序多种类型的数据,没错,它就是“qsort”函数 。那么,这个函数如何理解与实现呢?就是这篇文章的目的所在。
首先,“qsort”函数即为“quick sort(快速排序)” ,官方的定义如下:
原版
译文
由上我们知道,
void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*));
这便是函数qsort的组成,不难发现,函数的形参多用(const) void*类型,这是因为并不知道将要排序的数组究竟是什么类型,所以使用void * (无类型指针)来保证函数的广泛性。
以下是函数的各个参数具体释义:
我们不妨用这个函数排序各个类型的数组:
1.整形数组
问题:将整形数组arr[]={6,5,4,3,2,1}进行升序排序。
代码如下:
解释:在compar函数中,为了实现升序,将无类型指针先通过(int*)强制转化为整形指针,再将整形指针解引用(*),这样如果*(int*p1)比*(int*p2)大,ruturn返回的就是>0的值,那么根据上述的compar函数的传递规则,当ruturn返回大于0的数时,使p1指向的元素位于p2指向的元素之后,从而实现了所谓的升序排序。
如果要实现降序,只需compar中return中减法的两个数调换位置即可。
即改为: return *(int*)p2-*(int*)p1;
运行结果如下:
2.字符型数组
问题:将字符型数组char arr[]={'A','B','C','D','E'}进行降序排序
本质不过是“换汤不换药”,但有一个问题,如何比较两字符串的大小呢?
方法:使用strcmp()函数进行字符串比较(Tip:使用此函数需包含头文件"string.h")
注: strcmp()函数是C语言标准库中的一个函数,它用于比较两个字符串。如果两个字符串相等,那么strcmp()函数返回0。如果字符串str1小于字符串str2,那么strcmp()函数返回小于0的值。如果字符串str1大于字符串str2,那么strcmp()函数返回大于0的值。
其使用规则如下:(以后会专门写一篇关于strcmp()函数的详细介绍)
而strcmp函数的返回值恰好与compar函数有着千丝万缕的联系,于是我们对上述的整形排序代码做如下改动即可得出本题代码及其运行结果:
3. 结构数据
题目:分别用升序排序结构数据Stu中的char name[20],int age.
对结构体数据的排序本质上和对整型数组以及字符数组的排序区别都不是很大,但也多了一些“新的知识”。
“ . ”操作符
在C语言中,我们可以使用"."操作符来访问结构体中的成员。"."是成员访问操作符,它允许我们访问结构体或联合体中的成员。
#include <stdio.h>
struct Student{
char name[50];
int age;
float score;
};
int main(){
struct Student s;
strcpy(s.name, "John Doe");
s.age = 20;
s.score = 80.5;
printf("Name: %s\n", s.name);
printf("Age: %d\n", s.age);
printf("Score: %.1f\n", s.score);
return 0;
}
指向结构体子数据的指针
在C语言中,->是一个整体,用于指向结构体中的子数据。 当你定义了一个结构体,并声明一个指针指向这个结构体时,可以使用->运算符来取出结构体中的数据。
具体来说,->运算符用于通过指针访问结构体的成员。例如,假设你有一个结构体
struct Person
,其中包含name
和age
两个成员,你可以通过指针p
和->运算符来访问这些成员:p->name
和p->age
。这相当于(*p).name
和(*p).age
。#include <stdio.h>
struct Student {
char name[50];
int age;
float score;
};
int main() {
struct Student s;
struct Student *ps = &s;
strcpy(ps->name, "John Doe");
ps->age = 20;
ps->score = 80.5;
printf("Name: %s\n", ps->name);
printf("Age: %d\n", ps->age);
printf("Score: %.1f\n", ps->score);
return 0;
}在这个例子中,我们创建了一个指向Student结构体的指针ps,并使用"->"操作符来访问和修改结构体的成员。"->"操作符是一个简写的方式,它允许我们通过指针访问结构体的成员。
代码如下:
运行结果: 这样就实现了对于结构体的排序操作了。
回到本文刚开始的问题,我们可能有这样的问题,冒泡排序真的只能对整型数组进行操作吗?
如果你想通过冒泡排序进行qsort相同的操作,不妨通过“改进”冒泡排序的原来的代码来实现模拟函数qsort,从而获得“加强版的冒泡排序”
下面我们不妨再试试看:
首先我们拿出之前冒泡排序的代码吧:
我们看一下实现后的代码:(这里就以整型数组为例,本质只要改变cmp函数以及Print函数的数据类型即可针对任意数据类型了)
再来看看运行结果:
通过这样的方式,我们就可以更加深入的理解冒泡排序与函数qsort~~~~~~~~~~~~~~~~~~~!
以上就是本章的内容了,后续我还会对数组,指针等相关的基础知识作详细的记录供大家参考,同时也会记录我在后面数据结构与算法知识的所学所想,水平有限,希望得到大家的指导,有问题的地方也希望大家指出!