c语言中库函数qsort是无类型排序,且需要引入头文件 #include <stdlib.h>,查文档发现:
void qsort (void* base, size_t num, size_t size,
int (*compar)(const void*,const void*));
注意:size_t在这里就是unsigned int
此函数需要传入四个参数,第一个参数是要排序的一组元素的首地址,第二个参数是要排序的元素的个数,第三个参数是元素所占有的字节数。
第四个参数明显是一个函数指针,指向返回值为int,形参列表为两个任意类型指针的函数。所以这个函数是需要我们自己写的,那么这跟排序有什么关系呢?
compar指针所指向的函数中,其中两个指针变量要接收的其实是要排序的一组元素中任意两个元素的地址,然后对这两个指针解引用后比较这两个值,假如解引用后的值是x和y,那么:
if (x>y){
return 1;
}
else if (x < y){
return -1;
}
return 0;
返回1代表升序排序,返回-1代表降序排序。接下来来写一写这个函数。
#include <stdio.h>
#include <windows.h>
#include <assert.h>
#include <stdlib.h>
int ComInt(const void *xp,const void *yp){//要排序的元素的任意两个元素的地址传入
assert(xp);//检测指针合法性
assert(yp);
const int* x = (const int*)xp;//将指针类型转换为要排序的元素的类型
const int* y = (const int*)yp;
if (*x > *y){//第一个大于第二个,返回1升序排序
return 1;
}
else if(*x < *y){//第一个小于第二个,返回-1降序排序
return -1;
}
else{
return 0;
}
}
int main(){
int arr[] = { 11,11, 5, 3, 6, 94, 64, 89, 6, 4, 9 };
size_t num = sizeof(arr) / sizeof(arr[0]);//求元素的个数
qsort(arr, num, sizeof(int),ComInt);
for (int i = 0; i < num; i++){
printf("%d\n", arr[i]);
}
}
?
运行结果如上图,此时如果要降序排序,只需要将if?else语句中的返回值-1和1调换位置即可。
那么接下来使用qsort函数来对一组字符串进行排序,字符串的比较规则如下:
从字符串左边开始,一次比较每个字符,直接出现差异、或者其中一个串结束为止。比如ABC与ACDE比较,第一个字符相同,继续比较第二个字符,由于第二个字符是后面一个串大,所以不再继续比较,结果就是后面个串大。
因为字符串只能用指针指向或者用数组进行保存,所以多个字符串要么用一维的指针数组保存,要么用二维数组保存,在这里我用一维的指针数组来保存多个字符串,便于理解。
#include <stdio.h>
#include <windows.h>
#include <assert.h>
#include <stdlib.h>
int ComChar(const void *xp, const void *yp){//xp和yp此时是二级指针
assert(xp);//检测指针合法性
assert(yp);
const char **x=(const char **)xp;//强转为char**类型
const char **y=(const char **)yp;
char *_x = *x;//一次解引用代表的是字符串
char *_y = *y;
while (*_x || *_y){//在解引用代表的是第一个字符,用循环来依此比较各个字符,直到出现结果
if (*_x > *_y){
return 1;
}
else if (*_x < *_y){
return -1;
}
_x++;
_y++;
}
return 0;
}
int main(){
char *arr2[] = { "acjif", "ajgija", "hgagg", "oijgoia", "djigeg" };
size_t num2 = sizeof(arr2) / sizeof(arr2[0]);
qsort(arr2, num2, sizeof(char *), ComChar);
for (int i = 0; i < num2; i++){
printf("%s\n", arr2[i]);
}
system("pause");
return 0;
}
以上代码要注意一点:在调用ComChar函数传参时是传递了任意两个数组元素的地址,也就是说传递的是字符串指针的地址,是一个二级指针,但是要进行比较的是字符串中的单个字符,所以在ComChar函数中要进行两次解引用才能得到单个的字符。运行结果如下:
?
|