1.qsort函数使用
作用:用于排序任意类型的数组
参数:void qsort(void *base,int size,int width,int (*cmp)(const int*,const int *);
对参数的一一解释:
void* base :数组的待排序的第一个元素(数组名)、
int size:数组元素的个数
int width;单个元素的字节大小,例如:sizeof(a[0])
int (*cmp)(const int*,const int *):比较函数,本身返回int 类型,前一个数据大于后一个数据返回整数,=0相等,<0返回负数
代码实现:(注意事项:用qsort函数,记得调用<stdlib.h>库函数)还有强制类型转换
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>//注意引用
int cmp(const void* p1, const void* p2)//const 防止数据被改变
{
return (*(int* )p1 - *(int* )p2);//这里使用(int*)强制性类型转换是因为void* 不可用来进行+-和解引用,要转换成(int * )类型才可以使用
}
void print2(int* s, int sz)
{
for (int i = 0; i < sz; i++)
{
printf("%d ", *(s + i));
}
}
int main()
{
int s[5] = { 1,5,4,5,6 };
int sz = sizeof(s) / sizeof(s[0]);
int width = sizeof(s[0]);
qsort(s, sz, width, cmp);
print2(s, sz);
return 0;
}
结果展示:
2.qsort函数来排序结构体类型
代码实现:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct stu{
char name[20];
int age;
};
int cmp(const void* p1, const void* p2)
{
return ((struct stu*)p1)->age - ((struct stu*)p2)->age;//强制性类型转换成结构体指针类型,需要注意的一个点是:p2->age为间接访问,p2前面记得不要加*
}
void print1(struct stu* p1, int sz)
{
for (int i = 0; i < sz; i++)
{
printf("%d ", (p1+i)->age);
}
printf("\n");
}
int cmp_name(const void* p1, const void* p2)
{
return ((struct stu*)p1)->name - ((struct stu*)p2)->name;//这证明里qsort还可以排序字符数组
}
void print2(struct stu* p1, int sz)
{
for (int i = 0; i < sz; i++)
{
printf("%s ", (p1 + i)->name);
}
}
void test1()
{
struct stu s[] = { {"zhangsan",15},{"lisi",18},{"wangwu",55} };
int sz = sizeof(s) / sizeof(s[0]);
int width = sizeof(s[0]);
qsort(s, sz, width, cmp);
print1(s, sz);
}
void test2()
{
struct stu s[] = { {"zhangsan",15},{"lisi",18},{"wangwu",55} };
int sz = sizeof(s) / sizeof(s[0]);
int width = sizeof(s[0]);
qsort(s, sz, width, cmp_name);
print2(s, sz);
}
int main()
{
test1();
test2();
}
结果展示:
3.qsort的函数实现用冒泡排序模拟
代码实现:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int cmp(const void* p1,const void* p2)
{
return (*(int*)p1 - *(int*)p2);
}
void swap(const void* p1, const void* p2,int width)
{
for (int i = 0; i < width; i++)//这里一个字节一个字节地转换使得这个函数可以使用任意类型的数组
{
int temp = *((char*)p1 + i);
*((char*)p1 + i) = *((char*)p2 + i);
*((char*)p2 + i) = temp;
}
}
void bubble(void* arr, int sz, int width, int (*cmp)(void*, void*))
{
for (int i = 0; i < sz; i++)
{
for (int j = 0; j < sz - 1 - i; j++)//冒泡排序不变之处
{
if (cmp((char*)arr + j * width, (char*)arr + (j + 1) * width) > 0)//把数组转换成char*型方便后续swap转换一个字节一个字节地换,
//(char*)arr + j * width表示待比较的第一个元素的首地址,(char*)arr + (j + 1) * width)表示第二个
//若返回数>0则交换,其他则不变
{
swap((char*)arr + j * width, (char*)arr + (j + 1) * width,width);//传待交换元素的首地址,传单个元素的字节为后面一个一节一个字节转换方便
}
}
}
}
int main()
{
int arr[] = { 2,5,88,4,455,12,1 };
int sz = sizeof(arr) / sizeof(arr[0]);
int width = sizeof(arr[0]);
bubble(arr, sz, width, cmp);//模拟qsort函数传参
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
结果展示: