模拟实现qsort()
什么是qsort()函数已经有很多前辈都介绍了,也可以上网搜。
不过简而言之就是可以将不同类型的数组根据自己编写的排序函数来将其中元素进行排序。
下面是我实现的qsort()函数。
还是有不能完全起作用的时候,详情请接着往下看。
#include <stdio.h>
#include <string.h>
void Swap(char* p1, char* p2, size_t size)
{
for (size_t i = 0; i < size; i++)
{
char temp = *p1;
*p1 = *p2;
*p2 = temp;
p1++;
p2++;
//只需要一字节一字节地交换里面的数据就行了
//所以选用在传入两者的数据char*来指定交换两者的地址
//再传入每个元素的大小,这样就可以通过遍历完成交换
}
}
//为了保证任意类型的数据都可以进行排序,使用void*来指向数组的首地址
void LZ_sort(void* base, size_t nitems, size_t size, int (*cmp)(const void*e1, const void*e2))
{
for (size_t i = 0; i < nitems - 1; i++)
{
for (size_t j = 0; j < nitems - i - 1; j++)
{
//j * size 表示第(j + 1)个元素(下标为0)
if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
{
Swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
}
}
}
}
对整数数组进行排列:
//这个是排列整数数组的
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
int main()
{
int arr[10] = { 5,344,2,6,4,3,1,64,53,56 };
int items = sizeof(arr) / sizeof(arr[0]);
int size = sizeof(arr[0]);
LZ_sort(arr, items, size, cmp_int);
for (int i = 0; i < items; i++)
{
printf("%d ", arr[i]);
}
}
代码结果:
对字符数组进行排列:
//这个是排列字符数组的
int cmp_chars(const void* e1, const void* e2)
{
return strcmp((char*)e1, (char*)e2);
}
int main()
{
char arr[10] = "hello,LZ!";
int items = sizeof(arr) / sizeof(arr[0]);
int size = sizeof(arr[0]);
LZ_sort(arr, items, size, cmp_chars);
for (int i = 0; i < items; i++)
{
printf("%c ", arr[i]);
}
}
代码结果:
对字符串数组进行排列:
//这个是排列字符串数组的
//但是不稳定,有可能不成功
int cmp_chars(const void* e1, const void* e2)
{
return strcmp((char*)e1, (char*)e2);
}
int main()
{
char str1[] = "Candy";
char str2[] = "Alice";
char str3[] = "Bob";
char* arr[] = { str1, str2, str3};
//事实上,系统应该是将str1 str2 str3当成char*,毕竟arr中的元素为char*类型
//也就是说,在cmp_chars 中进行比较的不一定是str1 str2 str3的内容,而是其地址所表示的不明字符串
int items = sizeof(arr) / sizeof(arr[0]);
int size = sizeof(arr[0]);
printf("%d %d %d\n", sizeof(arr), items, size);
LZ_sort(arr, items, size, cmp_chars);
for (int i = 0; i < items; i++)
{
printf("%s\n", arr[i]);
}
}
代码结果:
成功案例:
失败案例:
但是将arr数组这么写就行了:
char arr[][10] = { "Candy", "Alice", "Bob" };
//这里传入的就是字符串内容
代码结果:
对结构体进行排序:
按照结构体中整数进行排列:
//这个是排列结构体的
//结构体一定要在各函数前声明或定义!!!!!
struct list
{
char name[10];
int age;
};
//根据年龄排列
int cmp_strcut_int(const void* e1, const void* e2)
{
return ((list*)e1) -> age - ((list*)e2) -> age;
}
int main()
{
struct list s[3] = { {"Bob", 10}, {"Alice", 8}, {"Candy", 15} };
int items = sizeof(s) / sizeof(s[0]);
int size = sizeof(s[0]);
printf("%d %d %d\n", sizeof(s), items, size);
LZ_sort(s, items, size, cmp_strcut_int);
for (int i = 0; i < items; i++)
{
printf("%s %d\n", s[i].name, s[i].age);
}
}
代码结果:
按照结构体中字符串首字母进行排列:
//根据姓名首字母排列
int cmp_strcut_chars(const void* e1, const void* e2)
{
return strcmp(((list*)e1)->name , ((list*)e2)->name);
}
int main()
{
struct list s[3] = { {"Donb", 10}, {"Alice", 8}, {"Candy", 15} };
int items = sizeof(s) / sizeof(s[0]);
int size = sizeof(s[0]);
printf("%d %d %d\n", sizeof(s), items, size);
LZ_sort(s, items, size, cmp_strcut_chars);
for (int i = 0; i < items; i++)
{
printf("%s %d\n", s[i].name, s[i].age);
}
}
代码结果: