qsort函数的官方介绍: 点这里
qsort函数需要包含头文件
qsort函数有四个参数,逐一介绍
base:指向数组中要排序的第一个对象的指针,转换为void*
num:基数指向的数组中元素的个数。Size_t是一个无符号整型
size:数组中每个元素的字节大小。Size_t是一个无符号整型
compar:指向比较两个元素的函数的指针
这个函数被qsort反复调用以比较两个元素。这个函数的格式为
int compar (const void* p1, const void* p2);
这个函数需要做到为qsort提供参数。
返回值 | 含义 |
---|---|
小于0的值 | p1所指向的元素比p2所指向的元素“小”,需要排在p2前面 |
0 | p1所指向的元素和p2所指向的元素一样大 |
大于0的值 | p1所指向的元素比p2所指向的元素“大”,需要排在p2前面 |
补充说明 | 在vs中这三个值一般是1、0、-1 |
浮点数无法直接比较大小,这里的实现方法需要牢牢掌握
先需要宏定义一个EPS,值为1e-7,这是哥非常非常小的值(1×10^-7),当俩浮点数之差的绝对值小于EPS时,可以代表这俩浮点数相等。
#include
#include
#include//fabs//绝对值
#define EPS 1e-7 //判断浮点数是否位于0的一个很小的邻域内[-EPS,EPS]内
typedef struct STU
{
char name[10];
int age;
float TotalScore;
}Stu;
int CmpFloat(const void* p1, const void* p2)
{
if (fabs((*(float*)p1 - (*(float*)p2)) <= EPS))
{
return 0;
}
else if ((*(float*)p1 - (*(float*)p2) > EPS))
{
return 1;
}
else
{
return -1;
}
}
void TestFloat()
{
float arr[] = { 1.2f,3.4f,2.8f,8.4f,6.3f };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), CmpFloat);
}
int main()
{
TestFloat();
return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
//库函数qsort的使用
//void qsort (void* base,
// size_t num,
// size_t size,
// int (*compar)(const void*, const void*));
//char int float struct
#include
#include//qsort
#include//fabs//绝对值
#define EPS 1e-7 //判断浮点数是否位于0的一个很小的邻域内[-EPS,EPS]内
typedef struct STU
{
char name[10];
int age;
float TotalScore;
}Stu;
int CmpInt(const void* p1, const void* p2)
{
return ((*(int*)p1) - (*(int*)p2));
}
void TestInt()
{
int arr[] = { 7,5,9,1,3,2,4,6,8,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), CmpInt);
}
int CmpChar(const void* p1, const void* p2)
{
return ((*(char*)p1) - (*(char*)p2));
}
void TestChar()
{
char arr[] = "AKRZXIY";
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), CmpChar);
}
int CmpFloat(const void* p1, const void* p2)
{
if (fabs((*(float*)p1 - (*(float*)p2)) <= EPS))
{
return 0;
}
else if ((*(float*)p1 - (*(float*)p2) > EPS))
{
return 1;
}
else
{
return -1;
}
}
void TestFloat()
{
float arr[] = { 1.2f,3.4f,2.8f,8.4f,6.3f };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), CmpFloat);
}
int CmpStructName(const void* p1, const void* p2)
{
return strcmp((*(Stu*)p1).name,(*(Stu*)p2).name);
}
int CmpStructAge(const void* p1, const void* p2)
{
return ((*(Stu*)p1).age - (*(Stu*)p2).age);
}
int CmpStructTotal(const void* p1, const void* p2)
{
if (fabs((*(Stu*)p1).TotalScore - (*(Stu*)p2).TotalScore) <= EPS)
{
return 0;
}
else if (((*(Stu*)p1).TotalScore - (*(Stu*)p2).TotalScore) > EPS)
{
return 1;
}
else
{
return -1;
}
}
void TestStruct()
{
Stu stu[3] = { {"bb",10,300},{"aa",30,200},{"cc",20,100} };
int sz = sizeof(stu) / sizeof(stu[0]);
qsort(stu, sz, sizeof(stu[0]), CmpStructName);
qsort(stu, sz, sizeof(stu[0]), CmpStructAge);
qsort(stu, sz, sizeof(stu[0]), CmpStructTotal);
}
int main()
{
TestInt();
TestChar();
TestFloat();
TestStruct();
return 0;
}
void Swap(char* buf1, char* buf2, int size)//交换arr[j],arr[j+1]这两个元素
{
int i = 0;
char tmp = 0;
for (i = 0; i < size; i++)
{
tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
void bubble_sort(void* base, int num, int size, int (*cmp)(const void*, const void*))
{
int i = 0;
//趟数
for (i = 0; i < num - 1; i++)
{
int j = 0;
//一趟内部比较的对数
for (j = 0; j < num - 1 - i; j++)
{
//假设需要升序cmp返回>0,交换
if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)//两个元素比较,需要将arr[j],arr[j+1]的地址要传给cmp
{
//交换
Swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
}
}
}
}
void Swap(void* base, int j, size_t size)
{
int i = 0;
for (i = 0; i < size; i++)
{
char tmp = *((char*)base + j * size + i);
*((char*)base + j * size + i) = *((char*)base + (j+1) * size + i );
*((char*)base + (j+1) * size + i) = tmp;
}
}
void BubbleSort(void* base, size_t num, size_t size, int (*compar)(const void*, const void*))
{
int i = 0;
for (i = 0; i < num - 1; i++)
{
int j = 0;
for (j = 0; j < num - 1 - i; j++)
{
if (compar(((char*)base + j * size), ((char*)base + (j + 1) * size)) > 0)
{
Swap(base,j,size);
}
}
}
}
#define _CRT_SECURE_NO_WARNINGS 1
//库函数qsort的实现(用冒泡排序的思想)
//void qsort (void* base,
// size_t num,
// size_t size,
// int (*compar)(const void*, const void*));
//char int float struct
#include
#include//BubbleSort
#include//fabs//绝对值
#define EPS 1e-7 //判断浮点数是否位于0的一个很小的邻域内[-EPS,EPS]内
typedef struct STU
{
char name[10];
int age;
float TotalScore;
}Stu;
//写法一
//void Swap(char* buf1, char* buf2, int size)//交换arr[j],arr[j+1]这两个元素
//{
// int i = 0;
// char tmp = 0;
// for (i = 0; i < size; i++)
// {
// tmp = *buf1;
// *buf1 = *buf2;
// *buf2 = tmp;
// buf1++;
// buf2++;
// }
//}
//
//void bubble_sort(void* base, int num, int size, int (*cmp)(const void*, const void*))
//{
// int i = 0;
// //趟数
// for (i = 0; i < num - 1; i++)
// {
// int j = 0;
// //一趟内部比较的对数
// for (j = 0; j < num - 1 - i; j++)
// {
// //假设需要升序cmp返回>0,交换
// if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)//两个元素比较,需要将arr[j],arr[j+1]的地址要传给cmp
// {
// //交换
// Swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
// }
// }
// }
//
//}
//写法二
void Swap(void* base, int j, size_t size)
{
int i = 0;
for (i = 0; i < size; i++)
{
char tmp = *((char*)base + j * size + i);
*((char*)base + j * size + i) = *((char*)base + (j+1) * size + i );
*((char*)base + (j+1) * size + i) = tmp;
}
}
void BubbleSort(void* base, size_t num, size_t size, int (*compar)(const void*, const void*))
{
int i = 0;
for (i = 0; i < num - 1; i++)
{
int j = 0;
for (j = 0; j < num - 1 - i; j++)
{
if (compar(((char*)base + j * size), ((char*)base + (j + 1) * size)) > 0)
{
Swap(base,j,size);
}
}
}
}
int CmpInt(const void* p1, const void* p2)
{
return ((*(int*)p1) - (*(int*)p2));
}
void TestInt()
{
int arr[] = { 7,5,9,1,3,2,4,6,8,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
BubbleSort(arr, sz, sizeof(arr[0]), CmpInt);
}
int CmpChar(const void* p1, const void* p2)
{
return ((*(char*)p1) - (*(char*)p2));
}
void TestChar()
{
char arr[] = "AKRZXIY";
int sz = sizeof(arr) / sizeof(arr[0]);
BubbleSort(arr, sz, sizeof(arr[0]), CmpChar);
}
int CmpFloat(const void* p1, const void* p2)
{
if (fabs((*(float*)p1 - (*(float*)p2)) <= EPS))
{
return 0;
}
else if ((*(float*)p1 - (*(float*)p2) > EPS))
{
return 1;
}
else
{
return -1;
}
}
void TestFloat()
{
float arr[] = { 1.2f,3.4f,2.8f,8.4f,6.3f };
int sz = sizeof(arr) / sizeof(arr[0]);
BubbleSort(arr, sz, sizeof(arr[0]), CmpFloat);
}
int CmpStructName(const void* p1, const void* p2)
{
return strcmp((*(Stu*)p1).name, (*(Stu*)p2).name);
}
int CmpStructAge(const void* p1, const void* p2)
{
return ((*(Stu*)p1).age - (*(Stu*)p2).age);
}
int CmpStructTotal(const void* p1, const void* p2)
{
if (fabs((*(Stu*)p1).TotalScore - (*(Stu*)p2).TotalScore) <= EPS)
{
return 0;
}
else if (((*(Stu*)p1).TotalScore - (*(Stu*)p2).TotalScore) > EPS)
{
return 1;
}
else
{
return -1;
}
}
void TestStruct()
{
Stu stu[3] = { {"bb",10,300},{"aa",30,200},{"cc",20,100} };
int sz = sizeof(stu) / sizeof(stu[0]);
BubbleSort(stu, sz, sizeof(stu[0]), CmpStructName);
BubbleSort(stu, sz, sizeof(stu[0]), CmpStructAge);
BubbleSort(stu, sz, sizeof(stu[0]), CmpStructTotal);
}
int main()
{
TestInt();
//TestChar();
//TestFloat();
//TestStruct();
return 0;
}