//void qsort(void* base, size_t num, size_t size,int (*compar)(const void*e1, const void*e2));
#include<stdio.h>
#include<stdlib.h>
struct Stu
{
char name[20];
int age;
};
int cmp_stu_by_age(const void* e1, const void* e2)
{
return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
void test()
{
struct Stu s[3] = { { "zhangsan", 20 }, { "lisi", 30 }, { "wangwu", 10 } };
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);
}
int main()
{
test();
return 0;
}
//void qsort(void* base, size_t num, size_t size,int (*compar)(const void*e1, const void*e2));
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct Stu
{
char name[20];
int age;
};
int cmp_stu_by_name(const void* e1, const void* e2)
{
//比较名字就是比较字符串
//字符串比较不能直接<>=来比较,需要用到strcmp函数
return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
//return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
void test()
{
struct Stu s[3] = { { "zhangsan", 20 }, { "lisi", 30 }, { "wangwu", 10 } };
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
}
int main()
{
test();
return 0;
}
void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*));
第一个参数:待排序数组的首元素的地址
第二个参数:待排序数组的元素个数
第三个参数:待排序数组的每个元素的大小,单位为字节
第四个参数:是函数指针,比较两个元素的所用函数的地址,这个函数使用者自己实现,函数指针的两个参数是待比较的两个元素的地址
#include <stdio.h>
int int_cmp(const void* p1, const void* p2)
{
return (*(int*)p1 - *(int*)p2);
}
void _swap(void* p1, void* p2, int size)
{
int i = 0;
for (i = 0; i < size; i++)
{
char tmp = *((char*)p1 + i);
*((char*)p1 + i) = *((char*)p2 + i);
*((char*)p2 + i) = tmp;
}
}
void bubble(void* base, int count, int size, int(*cmp)(void*, void*))
{
int i = 0;
int j = 0;
for (i = 0; i < count - 1; i++)
{
for (j = 0; j < count - i - 1; j++)
{
if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
{
_swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
}
}
}
}
int main()
{
int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
//char *arr[] = {"aaaa","dddd","cccc","bbbb"};
int i = 0;
bubble(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp);
for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
这里给大家详细解释一下这个代码
为什么我们要写cmp((char*)base + j * size, (char*)base + (j + 1) * size)呢???
因为当j=0的时候,这个函数的参数就代表第一个元素和第二个元素的地址,强制类型转化为char*而不是Int*的原因是强制类型转化为Int*然后+1会让地址向后移动四个字节,对于如果我们给你传过来的是一个结构体类型,double型,float型就不合适,所以Int*不考虑,对于为什么要强制类型转换为char*指针,char*指针加1跳过一个字节,当我+size的时候就跳过size个字节,这是我们就把我们相邻两个元素的地址求出来了,然后把地址带到cmp这个函数中去了,但他返回cmp函数的值大于0,我们就进行交换,那我们应该怎么交换呢???这里我们就设计一个_swap函数,传的参数是(char*)base + j * size, (char*)base + (j + 1) * size, size,我们为什么还要传一个size呢?因为你应该告诉我你这个两个字符各是几个字节,让我交换相应的对数,所以我们应该把这个元素的大小传过去,我们进到_swap函数进行交换,交换完了过后再*p1++,*p2++指向下一个值 ,再进行下一组交换,接着我们再写出这行代码,看下面代码,进行正负数的返回,返回给cmp函数判断正负数,是整数就进行交换,希望大家能够理解
#include <stdio.h>
int int_cmp(const void* p1, const void* p2)
{
return (*(int*)p1 - *(int*)p2);
}
这是一个一般的冒泡排序的模型,上面的代码就只是这个一般的冒泡排序的一个升华,本质是没变的,里面的排序还是正常的将两个元素进行交换,直到交换成升序为止
这里再给大家做一下说明
使用bubble_sort的程序员一定要知道自己排序的是什么数据,他就应该知道如何比较待排序数组中的元素,实现bubble_sort函数的程序员,他不知道未来排序的数据类型,那程序员也不知道待比较的两个元素的类型
本章终!