今天早上突然想起qsort函数,就顺便写篇博客分享一下,也帮自己复习一下!
qsort函数主要用于数组中元素的排列,可以是顺序和逆序,数组中元素类型由使用者自己决定。下面先了解一下qsort函数:
很明显,qsort函数有四个参数,下面分别介绍:
一、void*base:它是一个没有指定类型的指针,在使用时,它指向的是要比较的数组的有元素地址,所以在对其传参时,通常使用数组名。
二、size_t num:它指的是数组中元素的个数,需要操作者自己计算。
三、size_t width:它指的是数组中元素的类型的大小,比如int类型的大小为4,等等。
四、int (__cdecl *compare )(const void *elem1, const void *elem2 ),这个东东看起来比较麻烦,其实它代表的是一个比较函数,这个比较函数的返回类型通常是大于0,小于0,和等于0的整数,函数的参数分别为两个无指定类型的指针,指向要比较的两个元素,具体类型由操作者自己决定。
现在,我们对qsort函数的定义有了一定的了解,下面来举一个实例体味一下:
//将数组arr中元素升序排序
int compare(const void* a, const void* b)
{
return (*(int*)a-*(int*)b);
}
int main()
{
int arr[10] = { 2,5,8,4,1,9,3,6,0,7 };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(int), compare);
for (int i = 0; i < sz; i++)
cout << arr[i] << " ";
return 0;
}
在这里插入代码片
以上代码就实现了数组arr的升序排序,如果操作者想对其实现降序排序,只需将compare函数中a和b的位置交换一下。
接下来,我们来尝试模拟实现qsort函数:
在这//qsort函数的模拟实现
int my_compare(const void* a, const void* b)
{
//比较a,b,若a>b,则返回正值
return (*(int*)a - *(int*)b);
}
//两个数值的交换
void swap(char* a, char* b,int size)
{
for (int i = 0; i < size; i++)
{
char tmp = *a;
*a = *b;
*b = tmp;
a++;
b++;
}
}
void my_qsort(void* p, int number, int size, int(*cmp)(const void*, const void*))
{
//函数参数分别为数组首元素地址,元素个数,每一个元素的大小,比较函数
for (int i = 0; i < number - 1; i++)
{
for (int j = 0; j < number - 1 - i; j++)
{
if (my_compare((char*)p + j * size, (char*)p + (j + 1) * size)>0)
swap((char*)p + j * size, (char*)p + (j + 1) * size,size);
}
}
}
int main()
{
int arr[10] = { 2,5,8,4,1,9,3,6,0,7 };
int sz = sizeof(arr) / sizeof(arr[0]);
my_qsort(arr, sz, sizeof(int), my_compare);
for (int i = 0; i < sz; i++)
cout << arr[i] << " ";
return 0;
}里插入代码片
由上面的代码可以知道其实qsort函数的主要部分就是一个比较函数和一个数值交换函数
可能存在疑问的地方是在qsort函数中为什么将p强制类型转换为char*,其实是因为将其转换为一个字节比较便于计算。
至于第二个循环中为什么是就J<size-1-i,其实原理和冒泡排序是一样的,排序过的元素就不需要再次进行比较,也可以降低时间复杂度,运行更快一点。
以上就是我对qsort函数的理解,还是个新手,如有错误,请大佬们斧正!