在实现qsort之前,我们先了解一下回调函数。
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。
我们基于冒泡排序的基础来完成这个排序。
冒泡排序:重复地走访过要排序的元素列,依次比较两个相邻的元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素已经排序完成。
这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。
现在我们来看看qsort函数的原型:
void qsort(void *base , int num , int size , int (*cmp)(const void * , const void *));
1.返回值为空
2.参数分别为:(1)(数组的)起始地址(2)元素个数 (3)每个元素的大小(字节大小) (4)一个比较函数(回调函数)的函数指针
ok,基于以上内容,我们一步一步来实现他的功能:
(1)my_qsort
void my_qsort(void *base, int len, int size, int(*int_cmp)(const void*, const void*))
{
int i = 0;
int flag = 0;
for (i = 0; i < len - 1; i++){
int j = 0;
for (j = 0; j < len - 1 - i; j++){
if ((int_cmp((char*)base + j*size, (char*)base + (j + 1)*size)) > 0){
flag = 1;
int_cmp((char*)base + j*size, (char*)base + (j + 1)*size);
}
}
if (flag == 0){
break;
}
}
}
由于我们不知道传入的数据是什么类型的,但是又知道它每一个元素的字节数。所以我们把每一个元素强转为char型,每次读取一字节,再加上相应的字节数,就能准确找到每个元素的地址了。
其中定义的flag如果还是等于0,说明他是有序的,无需排序,直接返回。
2.int_cmp(比较函数)
int int_cmp(const void *px,const void *py)
{
if (*(char*)px > *(char*)py){
return 1;
}
else if (*(char*)px < *(char*)py){
return -1;
}
else{
return 0;
}
}
3.swap(交换函数)
//一个字节一个字节交换
void swap(char *x,char *y,int size){
while (size--){
*y ^= *x;
*x ^= *y;
x++;
y++;
}
}
完整程序:
#include<stdio.h>
#include<stdlib.h>
int int_cmp(const void *px,const void *py)
{
if (*(char*)px > *(char*)py){
return 1;
}
else if (*(char*)px < *(char*)py){
return -1;
}
else{
return 0;
}
}
//一个字节一个字节交换
void swap(char *x,char *y,int size){
while (size--){
*y ^= *x;
*x ^= *y;
x++;
y++;
}
}
void my_qsort(void *base, int len, int size, int(*int_cmp)(const void*, const void*))
{
int i = 0;
int flag = 0;
for (i = 0; i < len - 1; i++){
int j = 0;
for (j = 0; j < len - 1 - i; j++){
if ((int_cmp((char*)base + j*size, (char*)base + (j + 1)*size)) > 0){
flag = 1;
int_cmp((char*)base + j*size, (char*)base + (j + 1)*size);
}
}
if (flag == 1){
break;
}
}
}
int main()
{
int arr[] = { 0, -2, -1, 8, 3, 45, 22, 67, 89, 100 };
int len = sizeof(arr) / sizeof(arr[0]);
my_qsort(arr, len, sizeof(int), int_cmp);
int i = 0;
for (i = 0; i < len; i++){
printf("%d ", arr[i]);
}
printf("\n");
system("pause");
return 0;
}
运行结果: