冒泡排序:
從第一個元素開始,依次比較相鄰的兩個元素,如果順序不對就交換它們。
經過一輪遍歷后,最大(或最小)的元素會排在最后。
重復進行上述步驟,直到沒有任何元素需要交換,即列表已經有序。
以上是一個冒泡排序,需要對它進行改進。
參考我寫的
qsort函數(任意類型數據排序)-CSDN博客文章瀏覽閱讀61次。int (*compar)(const void*p1, const void*p2),返回值是int 類型,返回值是一個整形,函數指針會根據返回值 >0 ==0https://blog.csdn.net/bkmoo/article/details/136356436?spm=1001.2014.3001.5501
由于冒泡排序的趟數不需要改變,因此需要改變1參數與比較用的2if(j = 0; j < sz - 1 - i; j++),3互換的功能int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;這三塊。
一、
void 接收任意類型 size_t無符號整形。因此前三個參數設置為了void* base, size_t sz, size_t length
if比較這里用int類型,第四個參數又要回調函數。因此第四個參數為int類型的函數指針int(*cmp)(const void* p1, const void* p2))
void bubble_sort(void* base, size_t sz, size_t length, int(*cmp)(const void* p1, const void* p2))
{
?? ?int i = 0;
?? ?for (i = 0; i < sz - 1; i++)
?? ?{
?? ??? ?int j = 0;
?? ??? ?for (j = 0; j < sz - 1 - i; j++)//sz - 1 - i
?? ??? ?{
?? ??? ??? ?if (cmp((char*)base + j * length,(char*)base+ (j + 1)* length)> 0) ?//寬度!第一個元素與第二個元素之間的間隔用char類型(一個字節),
?? ??? ??? ?{
?? ??? ??? ??? ?swap((char*)base + j * length, (char*)base + (j + 1)* length, length);
?? ??? ??? ?}
?? ??? ?}
?? ?}
}
二、
關鍵在if比較這里,cmp為回調函數(比較大小的函數<0,?=0,>0 ),回調函數中的兩個參數很重要。
base為void* 類型,強制類型轉換為char類型,char類型長度為1字節(我喜歡叫它手術刀),這里傳遞的一個元素的長度length就很關鍵,每次跳過一個char*length長度(一個元素長度)這樣就可以接收任意長度的元素了。
? ?if (cmp((char*)base + j * length,(char*)base+ (j + 1)* length)> 0)
三、
接著就是交換功能的實現。比如傳遞的是int類型的,length就是4,char*p1與char*p2隔著四個字節,兩兩互換就可以實現兩個元素的交換。
傳遞的是指針,需要先解引用出內容后進行交換。
swap((char*)base + j * length, (char*)base + (j + 1)* length, length);
void swap(char* p1, char* p2, size_t length)
{
?? ?int i = 0;
?? ?for (i = 0; i < length; i++)
?? ?{
?? ??? ?char cmp = *p1;
?? ??? ?*p1 = *p2;
?? ??? ?*p2 = cmp;
?? ??? ?p1++;
?? ??? ?p2++;
?? ?}
}
最后回調函數是由程序員自己設計,根據比較的類型或結構體,自己的需求,設置回調函數
例 :這里我比較的數組,設置了cmp_arr函數進行比較。
void print(int arr[], int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}printf("\n");
}void swap(char* p1, char* p2, size_t length)
{int i = 0;for (i = 0; i < length; i++){char cmp = *p1;*p1 = *p2;*p2 = cmp;p1++;p2++;}
}void bubble_sort(void* base, size_t sz, size_t length, int(*cmp)(const void* p1, const void* p2))
{int i = 0;for (i = 0; i < sz - 1; i++){int j = 0;for (j = 0; j < sz - 1 - i; j++)//sz - 1 - i{if (cmp((char*)base + j * length,(char*)base+ (j + 1)* length)> 0) //寬度!第一個元素與第二個元素之間的間隔用char類型(一個字節),{swap((char*)base + j * length, (char*)base + (j + 1)* length, length);}}}
}int cmp_arr(const void* p1, const void* p2)
{return *(int*)p1 - *(int*)p2;
}int main()
{int arr[] = { 1,3,2,5,6,4,9,7,8 };int sz = sizeof(arr) / sizeof(arr[0]);print(arr, sz);bubble_sort(arr,sz,sizeof(arr[0]),cmp_arr);print(arr, sz);return 0;
}