qsort函数
"Performs a quick sort."执行一个快速排序。
爆炸复杂的参数(对我现在来说😶🌫️)
#include<stdio.h>
viod qsort(void*base,size_t num,size_t width,int (*compare)(const void*elem1,const void*elem2));
许多参数类型使用void的原因是为了使函数应用范围更广,方便使用者使用(不是只局限于数字排序)
base 是要排序的目标数组首元素地址(Start of target array)
num是目标数组的元素个数(Arry size in elements)
(size_t类型是sizeof的返回类型)
width 是目标数组中一个元素的大小(Element size in bytes)
compare 是一个函数,需要使用qsort的人自己创造,返回值为int 用于比较数组之中两个元素之间的大小,e1 e2是数组中传给compare函数的两个元素。
“简单”地使用一下qsort函数
#include<stdio.h>
int compare(const void* p1,const void* p2)
{
return(*((int*)p1) - (*(int*)p2));
}
int main()
{
int arr[10] = { 1,2,5,7,6,8,9,4,3,10 };
int sz = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
int width = sizeof(arr[0]);
qsort(arr, sz, width, compare);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
实现结果
调用qsort时参数中使用的compare函数不需要写参数。
模拟实现qsort函数
使用冒泡排序作为模拟qsort算法
#include<stdio.h>
int compare(const void* e1, const void* e2)
{
return(*(int*)e1 - *(int*)e2);
}
void swap(const void* e1, const void* e2, size_t width)
{
int x = 0;
char tmp = 0;
for (x = 0; x < width; x++)
{
tmp = *((char*)e1+x);
*((char*)e1+x) = *((char*)e2+x);
*((char*)e2+x) = tmp;
}
}
void Bubblesort(void* base, size_t sz, size_t width, int (*compare)(const void*,const void*))
{
int i = 0;
int j = 0;
for (i = 0; i < sz-1; i++)
{
for (j = 0; j < sz - 1 - i; j++)
{
if (compare((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
{
swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
}
}
}
}
int main()
{
int arr[10] = { 1,2,3,6,5,8,7,9,10,4 };
int sz = sizeof(arr) / sizeof(arr[0]);
int width = sizeof(arr[0]);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
Bubblesort(arr, sz, width, compare);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
模拟过程总结
- 首先把自己带入开发者的角度进行布局的思考。
- 注意void*的使用,还有解引用指针的注意。
- 其中最重要的是函数传参的注意,是最核心的地方。比如在使用swap函数的时候传参要强制类型转换成(char*),这是为了让不同类型数组比较时更加兼容。
- 把swap函数强转和交换过程理解透