目录
函数指针--实现回调函数
1.要点明晰
普通的冒泡排序算法能排序的数据类型是确定的,因此在排序其他类型的数据的时,算法需要修改的地方较多,因此我们希望创建出来了一个可以排序任意数据类型的冒泡排序算法。
- 普通冒泡排序
void bubble(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz-1; i++)//确定趟数
{
int j = 0;
for (j = 0; j < sz - 1 - i;j++)//确定元素比较的次数
{
if (arr[j] > arr[j + 1])
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
这里如果想要排序结构体类型的数据,函数参数的类型是不匹配的
2.进阶使用
使用【冒泡排序】的算法,模拟实现一个排序函数,可以排序任意类型的数据
(1)实现过程(整形数据)
①函数初步构造
//int (*cmp)(const void* e1, const void* e2)
//e1是一个指针,存放了一个要比较的元素的地址
//e2是一个指针,存放了一个要比较的元素的地址
//e1指向的元素>e2指向的元素,返回>0的数字
//e1指向的元素==e2指向的元素,返回0
//e1指向的元素<e2指向的元素,返回<0的数字
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
void bubble_sort(void*base, size_t num, size_t size, int (*cmp)(const void *e1,const void *e2))
// 元素个数 每个元素的大小
{
int i = 0;
for (i = 0; i < num-1; i++)//确定趟数
{
int j = 0;
for (j = 0; j < num - 1 - i;j++)//确定元素比较的次数
{
//if (arr[j] > arr[j + 1])
if(cmp( )>0) 这里要清楚arr[j]和arr[j+1]的地址
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
void test()
{
int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);
}
- 找到每个元素的地址
② 函数完整构造
//int (*cmp)(const void* e1, const void* e2)
//e1是一个指针,存放了一个要比较的元素的地址
//e2是一个指针,存放了一个要比较的元素的地址
//e1指向的元素>e2指向的元素,返回>0的数字
//e1指向的元素==e2指向的元素,返回0
//e1指向的元素<e2指向的元素,返回<0的数字
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
void swap(char* buf1, char* buf2, size_t size)
{
int i = 0;
for (i = 0; i < size; i++)
{
char tmp = *buf1;
*buf1++ = *buf2;
*buf2++ = tmp;
}
}
void bubble_sort(void* base, size_t num, size_t size, int (*cmp)(const void* e1, const void* e2))
// 元素个数 每个元素的大小
{
int i = 0;
for (i = 0; i < num - 1; i++)//确定趟数
{
int j = 0;
for (j = 0; j < num - 1 - i; j++)//确定元素比较的次数
{
//if (arr[j] > arr[j + 1])
if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
{
//交换
swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
}
}
}
}
- 交换条件图示
③完整代码展示
void print_arr(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
//int (*cmp)(const void* e1, const void* e2)
//e1是一个指针,存放了一个要比较的元素的地址
//e2是一个指针,存放了一个要比较的元素的地址
//e1指向的元素>e2指向的元素,返回>0的数字
//e1指向的元素==e2指向的元素,返回0
//e1指向的元素<e2指向的元素,返回<0的数字
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
void swap(char* buf1, char* buf2, size_t size)
{
int i = 0;
for (i = 0; i < size; i++)
{
char tmp = *buf1;
*buf1++ = *buf2;
*buf2++ = tmp;
}
}
void bubble_sort(void* base, size_t num, size_t size, int (*cmp)(const void* e1, const void* e2))
// 元素个数 每个元素的大小
{
int i = 0;
for (i = 0; i < num - 1; i++)//确定趟数
{
int j = 0;
for (j = 0; j < num - 1 - i; j++)//确定元素比较的次数
{
//if (arr[j] > arr[j + 1])
if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
{
//交换
swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
}
}
}
}
void test()
{
int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
print_arr(arr, sz);
bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);
print_arr(arr, sz);
}
(2)实现过程(结构体数据)
①函数构造
struct Stu
{
char name[20];//20
int age;//4
};
int cmp_stu_by_age(const void* e1, const void*e2)//按照年龄比较
{
return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
int cmp_stu_by_name(const void* e1, const void* e2)//按照姓名比较
{
return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
void swap(char* buf1, char* buf2, size_t size)
{
int i = 0;
for (i = 0; i < size; i++)
{
char tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
void bubble_sort(void* base, size_t num, size_t size, int (*cmp)(const void* e1, const void*e2))
{
//冒泡排序的趟数
int i = 0;
for (i = 0; i < num - 1; i++)
{
//一趟冒泡排序
int j = 0;
for (j = 0; j < num - 1 - i; j++)
{
//if (arr[j] > arr[j + 1])
if(cmp((char*)base + j * size, (char*)base + (j + 1) * size)>0)
{
//交换
swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
}
}
}
}
void test2()//比较name
{
struct Stu arr[] = { {"zhangsan", 20}, {"lisi", 30}, {"wangwu", 15}};
int sz = sizeof(arr) / sizeof(arr[0]);//3
bubble_sort(arr, sz, sizeof(arr[0]), cmp_stu_by_name);
}
int main()
{
//测试bubble_sort,排序结构体的数据
test2();
return 0;
}
实现结果:
- 流程展示
②完整代码展示
#include <stdio.h>
#include <stdlib.h>
struct Stu
{
char name[20];//20
int age;//4
};
int cmp_stu_by_age(const void* e1, const void*e2)
{
return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
int cmp_stu_by_name(const void* e1, const void* e2)
{
return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
void swap(char* buf1, char* buf2, size_t size)
{
int i = 0;
for (i = 0; i < size; i++)
{
char tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
void bubble_sort(void* base, size_t num, size_t size, int (*cmp)(const void* e1, const void*e2))
{
//冒泡排序的趟数
int i = 0;
for (i = 0; i < num - 1; i++)
{
//一趟冒泡排序
int j = 0;
for (j = 0; j < num - 1 - i; j++)
{
//if (arr[j] > arr[j + 1])
if(cmp((char*)base + j * size, (char*)base + (j + 1) * size)>0)
{
//交换
swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
}
}
}
}
void test2()
{
struct Stu arr[] = { {"zhangsan", 20}, {"lisi", 30}, {"wangwu", 15}};
int sz = sizeof(arr) / sizeof(arr[0]);//3
bubble_sort(arr, sz, sizeof(arr[0]), cmp_stu_by_name);
}
int main()
{
//测试bubble_sort,排序结构体的数据
test2();
return 0;
}
结果: