C語言冒泡排序超全面實(shí)現(xiàn)流程
普通版冒泡排序
冒泡排序想必大家都很了解了吧,冒泡排序的算法思想就是兩兩比大小,一輪一輪比,每比完一輪排出一個數(shù)字的順序,那就讓我們先來看一個普通的冒泡排序代碼>
void bubble_sort(int arr[], int sz)//參數(shù)接收數(shù)組元素個數(shù) { int i = 0; for (i = 0; i < sz - 1; i++) { int j = 0; for (j = 0; j < sz - i - 1; j++) { if (arr[j] > arr[j + 1]) { int tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } } } } int main() { int arr[] = { 3,1,7,5,8,9,0,2,4,6 }; int sz = sizeof(arr) / sizeof(arr[0]); int i = 0; bubble_sort(arr, sz); for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } return 0; }
先看代碼效果>
可以看到數(shù)組中的內(nèi)容變成了由小到大的順序,那如何讓數(shù)組成為由大到小的順序呢?很簡單我們只需要把if (arr[j] > arr[j + 1])中的>改成<,我們來看看效果>
void bubble_sort(int arr[], int sz)//參數(shù)接收數(shù)組元素個數(shù) { int i = 0; for (i = 0; i < sz - 1; i++) { int j = 0; for (j = 0; j < sz - i - 1; j++) { if (arr[j] < arr[j + 1]) { int tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } } } } int main() { int arr[] = { 3,1,7,5,8,9,0,2,4,6 }; int sz = sizeof(arr) / sizeof(arr[0]); int i = 0; bubble_sort(arr, sz); for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } return 0; }
這樣就達(dá)到了我們最終的效果了。
但是我們發(fā)現(xiàn),普通的冒泡排序只能對整型的數(shù)據(jù)進(jìn)行排序而其它類型的則無法排序,這就不得不動動我們的發(fā)財(cái)?shù)男∧X袋,其實(shí)C語言庫函數(shù)中有一個qsort函數(shù),這里我們先學(xué)習(xí)一下qsort函數(shù)的使用方法:我們可以打開我們的MSDN這款軟件。
qosrt函數(shù)
打開MSDN搜索qsort我們可以看到函數(shù)的定義:
有道翻譯>
我們可以看到qsort函數(shù)參數(shù)分別是數(shù)組地址、數(shù)組元素個數(shù)、數(shù)組元素大小(字節(jié))、一個比較函數(shù),返回值為void.,其內(nèi)部實(shí)現(xiàn)了一個快速排序算法,對一個num元素進(jìn)行排序,每個元素都是width字節(jié),參數(shù)base是一個指針,指向要排序數(shù)組的首元素地址,qsort用已經(jīng)排序的元素覆蓋這個數(shù)組,compare是一個函數(shù)指針,再使用的同時我們要自己書寫比較函數(shù)int_cmp。
我們來代碼演示一下>
int int_cmp(const void* p1, const void* p2) { return (*(int*)p1 - *(int*)p2); } int main() { int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 }; int i = 0; qsort(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; }
看效果>
如果需要由大到小排序的話只需將int_cmp函數(shù)中的p1和p2互換就可以啦。
終極版冒泡排序
學(xué)完了qsort函數(shù),我們可以模仿qosrt函數(shù)來改裝我們的冒泡排序>
我們可以將我們的冒泡排序函數(shù)也改為四個參數(shù):
void bubble_sort(void* base, size_t sz, size_t width, int(*cmp)(const void*, const void*))
比較函數(shù)部分>
int cmp_int(const void* e1, const void* e2) { return *(int*)e1 - *(int*)e2; } int cmp_by_name(const void* e1, const void* e2) { return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name); } int cmp_by_age(const void* e1, const void* e2) { return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age; }
分別為int、結(jié)構(gòu)體字符型、結(jié)構(gòu)體整型。
冒泡排序函數(shù)>
void bubble_sort(void* base, size_t sz, size_t width, int(*cmp)(const void*, const void*)) { size_t i = 0; for (i = 0; i < sz - 1; i++) { size_t j = 0; for (j = 0; j < sz - 1 - i; j++) { if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0) { Swap((char*)base + j * width, (char*)base + (j + 1) * width, width); } } } }
Swap函數(shù)>
void Swap(char* buf1, char* buf2, int width) { int i = 0; for (i = 0; i < width; i++) { char tmp = *buf1; *buf1 = *buf2; *buf2 = tmp; buf1++; buf2++; } }
Swap函數(shù)的功能是將元素以一個字節(jié)的大小進(jìn)行交換交換width次。
這樣我們就可以寫出可以排序任意類型元素的冒泡排序了
終極版冒泡排序整體測試代碼
struct Stu { char name[20]; int age; }; int cmp_int(const void* e1, const void* e2) { return *(int*)e1 - *(int*)e2; } int cmp_by_name(const void* e1, const void* e2) { return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name); } int cmp_by_age(const void* e1, const void* e2) { return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age; } void Swap(char* buf1, char* buf2, int width) { int i = 0; for (i = 0; i < width; i++) { char tmp = *buf1; *buf1 = *buf2; *buf2 = tmp; buf1++; buf2++; } } void bubble_sort(void* base, size_t sz, size_t width, int(*cmp)(const void*, const void*)) { size_t i = 0; for (i = 0; i < sz - 1; i++) { size_t j = 0; for (j = 0; j < sz - 1 - i; j++) { if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0) { Swap((char*)base + j * width, (char*)base + (j + 1) * width, width); } } } } void test1() { int arr[10] = { 2,5,9,1,3,6,4,7,8,0 }; int sz = sizeof(arr) / sizeof(arr[0]); bubble_sort(arr, sz, sizeof(arr[0]), cmp_int); int i = 0; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } printf("\n"); } void test2() { struct Stu a[3] = { {"zhangsan",18},{"lisi",15},{"wangwu",25} }; int sz = sizeof(a) / sizeof(a[0]); bubble_sort(a, sz, sizeof(a[0]), cmp_by_name); int i = 0; for (i = 0; i < sz; i++) { printf("%s ", a[i].name); } printf("\n"); } void test3() { struct Stu a[3] = { {"zhangsan",18},{"lisi",15},{"wangwu",25} }; int sz = sizeof(a) / sizeof(a[0]); bubble_sort(a, sz, sizeof(a[0]), cmp_by_age); int i = 0; for (i = 0; i < sz; i++) { printf("%d ", a[i].age); } printf("\n"); } int main() { test1(); test2(); test3(); return 0; }
運(yùn)行結(jié)果>
到此這篇關(guān)于C語言冒泡排序超全面實(shí)現(xiàn)流程的文章就介紹到這了,更多相關(guān)C語言冒泡排序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言實(shí)現(xiàn)三子棋小游戲(vs2013多文件)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)三子棋小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06C++使用遞歸和非遞歸算法實(shí)現(xiàn)的二叉樹葉子節(jié)點(diǎn)個數(shù)計(jì)算方法
這篇文章主要介紹了C++使用遞歸和非遞歸算法實(shí)現(xiàn)的二叉樹葉子節(jié)點(diǎn)個數(shù)計(jì)算方法,涉及C++二叉樹的定義、遍歷、統(tǒng)計(jì)相關(guān)操作技巧,需要的朋友可以參考下2017-05-05C++實(shí)現(xiàn)第K順序統(tǒng)計(jì)量的求解方法
這篇文章主要介紹了C++實(shí)現(xiàn)第K順序統(tǒng)計(jì)量的求解方法,很有借鑒價(jià)值的算法,需要的朋友可以參考下2014-08-08