????????我們將詳細介紹一個基于冒泡排序算法的自定義排序函數——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`使用。
注意看注釋