一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情。
大家好,我是芒果,一名非科班的在校大学生。对C/C++、数据结构、Linux及MySql、算法等领域感兴趣,喜欢将所学知识写成博客记录下来。 希望该文章对你有所帮助!如果有错误请大佬们指正!共同学习交流
作者简介:
- CSDN C/C++领域新星创作者blog.csdn.net/chuxinchang…
- 掘金LV3用户 juejin.cn/user/138142…
- 阿里云社区专家博主,星级博主,技术博主 developer.aliyun.com/profile/exp…
- 华为云云享专家 bbs.huaweicloud.com/community/m…
2.qsort函数
函数说明:
qsort()函数:快速排序的函数 -引用stdlib.h头文件
参数说明:
void qsort(void* base, //要比较的数组
size_t num, //待排序的元素个数
size_t width, //一个元素的大小,单位是字节
int(*cmp)(const void* e1, const void* e2)); //cmp指向的是:排序时,用来比较两个元素的函数
关于void*指针
void* :无具体类型的指针
能够接收任意类型的地址
缺点:不能进行运算。不能+-整数,不能解引用
int a = 0;
float f = 5.5f;
void* p1 = &a;
void* p2 = &f;
排序整数数组
void Print(int* arr, int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", *(arr + i));
}
printf("\n");
}
//比较整形
//注意类型时void* 所以要强制类型转化,还要解引用才是对应的值!!!
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
void test1()
{
int arr[] = { 9,8,7,6,7,5,4,8 };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_int);
Print(arr, sz);
}
排序结构体数组
注意:结构体用大括号初始化
1.按名字比较->比较字符串-》strcmp函数
strcmp()返回值:和qsort刚好对应
strcmp()返回值
qsort返回值
struct Stu
{
int age;
char name[20];
};
//比较结构体中元素的年龄
int cmp_age(const void* e1, const void* e2)
{
//本质是比较整形
return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
//比较名字
int cmp_name(const void* e1, const void* e2)
{
//本质是字符串比较->使用strcmp函数
return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
void test2()
{
//创建结构体数组,用大括号初始化
struct Stu s[3] = { {19,"Mango"},{18,"Lemon"},{20,"Hello"} };
int sz = sizeof(s) / sizeof(s[0]);
//以年龄排
qsort(s, sz, sizeof(s[0]), cmp_age);
printf("%s %d ",s[0].name,s[0].age);
printf("%s %d ", s[1].name, s[1].age);
printf("%s %d ", s[2].name, s[2].age);
printf("\n");
//以姓名排
qsort(s, sz, sizeof(s[0]), cmp_name);
printf("%s %d ", s[0].name, s[0].age);
printf("%s %d ", s[1].name, s[1].age);
printf("%s %d ", s[2].name, s[2].age);
printf("\n");
}
排序浮点型数组
//写法1:可能会出错
// 原因: 0.2 -0.1 = 0.1 强制类型转化为int后 结果为0
//int cmp_float(const void* e1, const void* e2)
//{
// //返回类型是int 所以相减后的结果要强制类型转化
// return (int)(*(float*)e1 - *(float*)e2);
//}
//写法2:对应上qsort的返回值
int cmp_float(const void* e1, const void* e2)
{
if ((*(float*)e1 - *(float*)e2) > 0.00000)
return 1;
else if ((*(float*)e1 - *(float*)e2) == 0.000000)
return 0;
else
return -1;
}
void test3()
{
float arr[5] = { 5.01f,5.01f,0.02f,0.01f,5.001f };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_float);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%f ", arr[i]);
}
}
排序字符数组
//注意要要强制类型转换!! 要解引用!!! 本质上是比较Ascii值
int cmp_char(const void* e1, const void* e2)
{
return *(char*)e1 - *(char*)e2;
}
void test4()
{
char arr[] ="mango";
//若使用sizeof计算长度:
//int sz = sizeof(arr) / sizeof(arr[0]); //6
//qsort(arr, sz-1, sizeof(arr[0]), cmp_float);
//因为sizeof把\0也算进去了,所以计算出来的值比字符串本身长度多1
int sz = strlen(arr); //5
qsort(arr, sz, sizeof(arr[0]), cmp_char);
printf("%s\n",arr);
}
排序字符指针数组
//err程序
int cmp_chars(const void* e1, const void* e2)
{
return strcmp((char*)e1, *(char*)e2);
}
void test2()
{
char* arr1 = "abc";
char* arr2 = "wcad";
char* arr3 = "cab";
char* p[3] = { arr1,arr2,arr3 };
int sz = sizeof(p) / sizeof(p[0]);
qsort(p, sz, sizeof(p[0]), cmp_chars);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%s\n", p[i]);
}
}
上述程序错误原因:把p传给qsort,p是数组名->首元素地址,元素类型为char*>,所以p的地址类型为:char**类型
//正确程序
//将e1和e2强制类型转化为char** 然后解引用找到对应的字符串的地址
int cmp_chars(const void* e1, const void* e2)
{
return strcmp(*(char**)e1, *(char**)e2);
}
void test2()
{
char* arr1 = "abc";
char* arr2 = "wcad";
char* arr3 = "cab";
char* p[3] = { arr1,arr2,arr3 };
int sz = sizeof(p) / sizeof(p[0]);
qsort(p, sz, sizeof(p[0]), cmp_chars);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%s\n", p[i]);
}
}
代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//qsort排序
//void qsort(void* base, //要比较的数组
// size_t num, //个数
// size_t width, //每一个元素的字节
// int(__cdecl* compare)(const void* elem1, const void* elem2));
void Print(int* arr, int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", *(arr + i));
}
printf("\n");
}
//比较整形
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
void test1()
{
int arr[] = { 9,8,7,6,7,5,4,8 };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_int);
Print(arr, sz);
}
struct Stu
{
int age;
char name[20];
};
//比较结构体中元素的年龄
int cmp_age(const void* e1, const void* e2)
{
//本质是比较整形
return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
//比较名字
int cmp_name(const void* e1, const void* e2)
{
//本质是字符串比较->使用strcmp函数
return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
void test2()
{
//创建结构体数组,用大括号初始化
struct Stu s[3] = { {19,"Mango"},{18,"Lemon"},{20,"Hello"} };
int sz = sizeof(s) / sizeof(s[0]);
//以年龄排
qsort(s, sz, sizeof(s[0]), cmp_age);
printf("%s %d ",s[0].name,s[0].age);
printf("%s %d ", s[1].name, s[1].age);
printf("%s %d ", s[2].name, s[2].age);
printf("\n");
//以姓名排
qsort(s, sz, sizeof(s[0]), cmp_name);
printf("%s %d ", s[0].name, s[0].age);
printf("%s %d ", s[1].name, s[1].age);
printf("%s %d ", s[2].name, s[2].age);
printf("\n");
}
//比较浮点型数据
//写法1:可能会出错
// 原因: 0.2 -0.1 = 0.1 强制类型转化为int后 结果为0
//int cmp_float(const void* e1, const void* e2)
//{
// //返回类型是int 所以相减后的结果要强制类型转化
// return (int)(*(float*)e1 - *(float*)e2);
//}
//写法2:对应上
int cmp_float(const void* e1, const void* e2)
{
if ((*(float*)e1 - *(float*)e2) > 0.00000)
return 1;
else if ((*(float*)e1 - *(float*)e2) == 0.000000)
return 0;
else
return -1;
}
void test3()
{
float arr[5] = { 5.01f,5.01f,0.02f,0.01f,5.001f };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_float);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%f ", arr[i]);
}
printf("\n");
}
//注意要要强制类型转换!! 要解引用!!! 本质上是比较Ascii值
int cmp_char(const void* e1, const void* e2)
{
return *(char*)e1 - *(char*)e2;
}
void test4()
{
char arr[] ="mango";
//若使用sizeof计算长度:
//int sz = sizeof(arr) / sizeof(arr[0]); //6
//qsort(arr, sz-1, sizeof(arr[0]), cmp_float);
//因为sizeof把\0也算进去了,所以计算出来的值比字符串本身长度多1
int sz = strlen(arr); //5
qsort(arr, sz, sizeof(arr[0]), cmp_char);
printf("%s\n",arr);
}
int main()
{
//排序整形数组
test1();
//排序结构体数组
test2();
//排序浮点型数据
test3();
//排序字符数组
test4();
return 0;
}