qsort函数的使用
在这里我们先了解一下qsort 快排的使用方法,我们可以利用c++类似图书馆的一个网站来查询我们想要用到的函数。
找到这之后我们能知道qsort的基本用法,如果实在不知道这些英文什么意思,我们可以借助一些翻译软件进行翻译,以便更容易了解。
好了,讲到这里,我们就写一下我们的代码实现一下吧。
代码如下:
#include<stdlib.h>
#include<stdio.h>
typedef struct stu {
//这里定义了一个结构体类型s
char name[50];
int age;
}s;
typedef struct Str {
//这是把一个字符数组放在我们的结构体当中,为的是方便实现我们的字符串排序
char str[50];
}k;
int cmp_age(const void* p1, const void* p2)//这是针对结构体s中的age排序实现的一个函数
{
return ((s*)p1)->age - ((s*)p2)->age;//这里是把void*强制转换成结构体指针s*,通过s*再来找到结构体成员age进行排序
}
int cmp_name(const void* p1, const void* p2)//这是针对结构体s中的name排序实现的一个函数
{
return strcmp(((s*)p1)->name, ((s*)p2)->name);//这里是把void*强制转换成结构体指针s*,通过s*再来找到结构体成员name进行排序
}
void print_arr(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)//打印整型数组,方便看排序后的数组
{
printf("%d ", arr[i]);
}
printf("\n");
}
void print_str(k arr[], int sz)//打印排序后的字符串
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%s ",arr[i].str);
}
printf("\n");
}
void print_struct(s arr[],int sz)//打印结构体成员的值
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("(姓名:%s 年龄:%d) ", arr[i].name, arr[i].age);
}
printf("\n");
}
int cmp_str(const void* p1, const void* p2)//针对字符串排序实现的一个比较函数
{
return strcmp(((k*)p1)->str, ((k*)p2)->str);
}
int cmp_int(const void* p1, const void* p2)//针对整型数据排序实现的一个比较函数
{
return *(int*)p1 - *(int*)p2;
}
void test()
{
int arr1[] = {
1,3,5,7,9,2,4,6,8,10 };
int sz1 = sizeof(arr1) / sizeof(arr1[0]);
s arr2[] = {
{
"zhangsan",22},{
"lisi",33},{
"wangwu",44} };
int sz2 = sizeof(arr2) / sizeof(arr2[0]);
k str[] = {
{
"sunwenchao"},{
"pengge"},{
"laowang"} };
int sz3 = sizeof(str) / sizeof(str[0]);
qsort(arr1, sz1, sizeof(arr1[0]), cmp_int);
printf("排序后的数组为:\n");
print_arr(arr1, sz1);
qsort(arr2, sz2, sizeof(arr2[0]), cmp_age);
printf("按年龄排序:\n");
print_struct(arr2, sz2);
qsort(arr2, sz2, sizeof(arr2[0]), cmp_name);
printf("按名字排序:\n");
print_struct(arr2, sz2);
qsort(str, sz3, sizeof(str[0]), cmp_str);
printf("排序后的字符串顺序为:\n");
print_str(str, sz3);
}
int main()
{
test();
return 0;
}
以上我已经对三种类型的数据进行了排序,运行结果如下:
使用冒泡排序思想模拟实现qsort函数
我们通过上述已经知道了qsort是怎么使用的,那么我相信小伙伴们肯定对他的实现方法非常好奇,为什么它可以对这么多种类型的数据排序呢?相比你肯定很想知道吧,那就让我们来模拟一下。
实现的代码如下:
#include<stdio.h>
//打印遍历一个整型数组的每个元素
void print(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
//这是一个交换函数,可以用来交换任意类型的数组元素
//像整型,字符型数组的元素,结构体类型的结构体成员
//这里的width指的是一个数组元素所占的字节数
//因为char类型的一个字符占用一个字节,一个整型是占四个字节,
//那么交换四个char型的字节也就是一个width实现交换一个整形元素
void swap(char* s1, char* s2, size_t width)
{
size_t i = 0;
for (i = 0; i < width; i++)
{
char temp = *s1;
*s1 = *s2;
*s2 = temp;
s1++;//交换了一个字节之后继续往后移动,直到交换了width个字节
s2++;
}
}
//这是一个该排序函数使用者自定义的一个函数,
//如果你想要排什么类型的数据就需要把该函数的参数p1,p2
//强转成相应类型的指针进行比较
int cmp_int(const void* p1, const void* p2)
{
return *(int*)p1 - *(int*)p2;
}
void bubble_sort(void* base, size_t count, size_t width, int (*cmp_int)(const void*, const void*))
{
size_t i = 0;//定义i为无符号整数
for(i = 0; i < count; i++)
{
int flag = 1;//假设待排序数组有序
size_t j = 0;//定义j为无符号整数
for (j = 0; j < count - i - 1; j++)
{
//默认排序成升序,若想要排成降序只需要把">0"修改成"<0"
if (cmp_int((char*)base + j * width, (char*)base + (j + 1) * width)>0)
{
flag = 0;
swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
}
}
if (flag == 1)//如果上述循环数组元素一次都没有交换,
{
//说明有序,则flag没有被赋值为0,则不再需要继续多余的交换过程了
break;
}
}
}
int main()
{
//使用冒泡排序的思想模拟实现qsort的使用方法
int arr[] = {
4,3,1,0,2,5,8,6,10,9,7 };
int sz = sizeof(arr) / sizeof(arr[0]);//该数组的大小,即有多少个元素
bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);
print(arr, sz);//打印排序后的数组
return 0;
}
运行结果是:
是不是感觉有点奇妙啊!
后面还有更多让我们觉得神奇的知识等着我们去探索呢!
让我们继续向我们的IT生涯前进吧,加油冲冲冲!