qsort函数是什么?
平时我们在写排序算法时都只能对固定的类型进行排序而qsort是一种可以对任意类型数据进行排序的函数。函数原型:
void qsort (void* base, size_t num, size_t size, int (compar)(const void,const void*);
base:指向你需要排序的数据的第一个元素;
num:你需要排序的元素个数;
size:待排序数据中单个元素的大小,单位字节;
int (compar)(const void,const void*):这是一个函数指针,他的返回值是int,当第一个参数指向的数据大于第二个参数指向的数据时返回大于0的数;相等返回0;否则就返回小于0的数
最后一个参数其实是然用户自己实现一个比较函数对两个数据
进行比较然后按要求进行返回。
为什么base的类型为void*?
之所以base的类型是void*,因为void类型的指针可以接收任意类型的指针比如:结构体指针,数组指针,字符指针……都可以被void类型的指针所接收。
而需要用户亲自写的比较函数其实一点也不难因为不管是数字,字符或是字符串都非常简单:
//如果是浮点型酒吧int换成float或double,字符也一样
int Compare(const void* p1, const void* p2)
{
return *((int*)p1) - *((int*)p2);
}
//字符串,因为strcmp函数的返回值刚好满足此要求所以可以直接调用
#include <string.h>
int Compare(const void* p1, const void* p2)
{
return strcmp((char*)p1 ,(char*)p2);
}
思路分析
因为比较函数是用户自己传进来的所以我们利用冒泡排序的思想实现qsort时就不需要进行比较了可以直接调用用户传进来的比较函数:
void My_qsort(void* base, int num, int size, int (*p)(const void*, const void*))
{
for (int i = 0; i < num - 1; i++)
{
for (int j = 0; j < num - 1; j++)
{
//需要特别注意虽然void*类型的指针可以接收所有类型的指针但是却无法对其进行访问所以这里必须进行强制类型转换
if (p((char*)base + size * j, (char*)base + size * (j + 1)) > 0)
{
//对数据进行交换
Swape((char*)base + size * j, (char*)base + size * (j + 1), size);
}
}
}
}
为了使代码更加简洁所以我将数据的交换单独用写成了一个函数:
void Swape(char* q1, char* q2, int size)
{
for (int i = 0; i < size; i++)
{
char tmp = *q1;
*q1 = *q2;
*q2 = tmp;
q1++;
q2++;
}
}
完整代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
int Compare(const void* p1, const void* p2)
{
return *((int*)p1) - *((int*)p2);
}
void Swape(char* q1, char* q2, int size)
{
for (int i = 0; i < size; i++)
{
char tmp = *q1;
*q1 = *q2;
*q2 = tmp;
q1++;
q2++;
}
}
void My_qsort(void* base, int num, int size, int (*p)(const void*, const void*))
{
for (int i = 0; i < num - 1; i++)
{
for (int j = 0; j < num - 1; j++)
{
if (p((char*)base + size * j, (char*)base + size * (j + 1)) > 0)
{
//交换
Swape((char*)base + size * j, (char*)base + size * (j + 1), size);
}
}
}
}
int main()
{
int arr[] = {
2.6,4.3,9,23,8,0,9,2};
int num = sizeof(arr) / sizeof(arr[0]);
My_qsort(arr, num, sizeof(arr[0]), Compare);
for (int i = 0; i < num; i++)
{
printf("%d ", arr[i]);
}
return 0;
}