我们将详细介绍一个基于冒泡排序算法的自定义排序函数——Mysqrt
。该函数通过使用用户提供的比较函数进行元素间的比较,并结合swap
交换函数对任意类型的数据进行排序。下面是对代码的逐行解析。
逻辑导图
代码实现
// 头文件
#include<stdio.h>
// 定义比较函数,用于决定两个元素之间的大小关系
int Mycompares(const void *p1, const void *p2) {
// 这里假设传入的是整型指针,将指针转换为整型并做差,返回结果作为比较依据
return (*(int*)p1 - *(int*)p2);
}
// 定义交换函数,用于交换两个内存区域的内容
void swap(char* p1, char* p2, size_t size) {
for (int i = 0; i < size; i++) {
// 临时变量存储p1的当前值
char tmp = *p1;
// 将p2的值赋给p1
*p1 = *p2;
// 将临时变量tmp(即原p1的值)赋给p2
*p2 = tmp;
// 指针指向下一个待交换的元素
p1++;
p2++;
}
}
// 自定义冒泡排序函数
void Mysqrt(void* base, size_t num, size_t size, int (*cmp)(const void*, const void*)) {
// 遍历数组,num-1轮冒泡以确保所有元素有机会排序到位
for (int i = 0; i < num - 1; i++) {
// 内层循环负责每轮冒泡的具体操作
for (int j = 0; j < num - 1 - i; j++) {
// 使用cmp函数比较相邻元素的大小
if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0) {
// 如果逆序,则调用swap函数交换两个元素的位置
swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
}
}
}
}
// 打印原始数组函数
void Print1(int* p, int sz) {
printf("排序前:");
for (int i = 0; i < sz; i++) {
printf("%d: ", *(p + i));
}
printf("\n");
}
// 打印已排序数组函数
void Print2(int *p, int sz) {
printf("排序后:");
for (int i = 0; i < sz; i++) {
printf("%d: ", *(p + i));
}
}
// 测试函数
void text() {
// 初始化一个整数数组
int arr[] = { 2,1,3,6,5,4,9,8,7,0 };
// 计算数组元素个数
int sz = sizeof(arr) / sizeof(arr[0]);
// 输出原始数组
Print1(arr, sz);
// 调用Mysqrt对数组进行排序
Mysqrt(arr, sz, sizeof(arr[0]), Mycompares);
// 输出排序后的数组
Print2(arr, sz);
}
// 主函数
int main() {
// 调用测试函数
text();
return 0;
}
### 函数参数解释:
- `Mysqrt`函数:
- 参数`base`:指向数组起始位置的指针。
- 参数`num`:数组中元素的数量。
- 参数`size`:每个元素占用的字节数,用于计算元素地址偏移。
- 参数`cmp`:指向比较函数的指针,用于决定元素间的大小关系。
- `swap`函数:
- 参数`p1`和`p2`:分别指向需要交换的两个元素的起始地址。
- 参数`size`:每个元素的大小,用于循环控制交换内容。
- `text`函数中调用`Mysqrt`时,`arr`作为`base`参数传递,`sz`作为`num`,`sizeof(arr[0])`表示每个整数元素所占的字节数,`Mycompares`作为比较函数提供给`Mysqrt`使用。
注意看注释