冒泡排序是咱們大多數人接觸到的第一種排序算法,原理簡單易懂,很少解釋。說明三點:ios
1. 冒泡排序是穩定排序,只有當兩個元素不一樣時纔會交換; git
2. 冒泡排序是原址排序,不須要藉助額外的空間;github
3. 冒泡排序一般見到的都是經過循環來實現的,其實經過遞歸來實現更簡潔。 redis
4. 冒泡排序的時間複雜度爲O(N*N)算法
代碼以下所示:編程
1 /*********************************************************************** 2 * Copyright (C) 2019 Yinheyi. <chinayinheyi@163.com> 3 * 4 * This program is free software; you can redistribute it and/or modify it under the terms 5 * of the GNU General Public License as published by the Free Software Foundation; either 6 * version 2 of the License, or (at your option) any later version. 7 8 * Brief: 9 * Author: yinheyi 10 * Email: chinayinheyi@163.com 11 * Version: 1.0 12 * Created Time: 2019年05月08日 星期三 21時53分25秒 13 * Modifed Time: 2019年05月08日 星期三 23時48分18秒 14 * Blog: http://www.cnblogs.com/yinheyi 15 * Github: https://github.com/yinheyi 16 * 17 ***********************************************************************/ 18 19 20 // 對於冒泡排序,這確定是你們接觸編程時第一個碰到的排序算法。 21 // 原理很簡單: 以從小到大排序爲例,假設一個數組的長度爲n, 則: 22 // 第一次: 從數組尾部開始向前, 兩兩元素之間進行比較, 共比較n-1次,就能夠把最小元素移 23 // 動到數組下標爲0的地方, 此時有1個排序完成, 剩餘n-1個尚未排序。 24 // 第二次:仍是從數組尾部開始向前,兩兩元素之間進行比較, 共比較n-2次,就能夠把剩餘的 25 // 元素中最小的元素移動到數組下標爲1的地方,此時有2個元素排序完成,剩餘n-2尚未排序。 26 // 第三次: 重複以上過程。 27 // 28 // 原始 第一次 第二次 第三次 第四次 第五次 29 // 3 -12 -12 -12 ... ... 30 // 2 3 1 1 31 // 8 2 3 1 32 // 1 8 2 3 33 // -12 1 8 2 34 // 32 1 1 8 35 // 1 32 32 32 36 // 37 // 38 // 說明:1. 冒泡排序是穩定排序,只有當兩個元素不一樣時纔會交換; 39 // 2. 冒泡排序一般見到的都是經過循環來實現的,其實經過遞歸來實現更簡潔。 40 // 3. 冒泡排序的時間複雜度爲O(N*N) 41 // 42 // 43 bool less(int lhs, int rhs); 44 bool greate(int lhs, int rhs); 45 static inline void swap(int& lhs, int & rhs); 46 void PrintArray(int array[], int nLength_); 47 typedef bool (*Comp)(int, int); 48 49 // 基於循環來實現的冒泡排序: 50 void BubbleSort_Loop(int array[], int nLength_, Comp CompFunc) 51 { 52 if (array == nullptr || nLength_ <= 1 || CompFunc == nullptr) 53 return; 54 55 // 對於n個元素,只須要排前n-1個元素便可, 即下標爲0, 1, 2, ..., n-2的元素。 56 for (int i = 0; i < nLength_ - 1; ++i) 57 { 58 // 若是要使下標爲i的元素變成有序的,須要從數組尾部開始兩兩交換,直至交換到i 59 for (int j = nLength_ - 1; j > i; --j) 60 { 61 if (!CompFunc(array[j-1], array[j])) 62 { 63 swap(array[j-1], array[j]); 64 } 65 } 66 } 67 } 68 69 // 基於遞歸來實現冒泡排序: 70 void BubbleSort_Recursion(int array[], int nLength_, Comp CompFunc) 71 { 72 if (array == nullptr || nLength_ <= 1 || CompFunc == nullptr) 73 return; 74 75 // 從數組尾部向前,對不符合要求的元素進行兩兩交換,從而使數組頭部的元素爲最小或最大 76 for (int i = nLength_ - 1; i > 0; --i) 77 { 78 if (!CompFunc(array[i-1], array[i])) 79 { 80 swap(array[i-1], array[i]); 81 } 82 } 83 84 // 對數組剩餘的元素進行遞歸操做 85 BubbleSort_Recursion(array + 1, nLength_ - 1, CompFunc); 86 } 87 88 // 小小的測試 89 #include <iostream> 90 /*************** main.c *********************/ 91 int main(int argc, char* argv[]) 92 { 93 int test1[10] = {-1, -23, 33, 423, -2349, 1, 1, 0, 9, 10}; 94 std::cout << "原順序爲:" << std::endl; 95 PrintArray(test1, 10); 96 97 std::cout << "基於循環的從小到大排序:" << std::endl; 98 BubbleSort_Loop(test1, 10, less); 99 PrintArray(test1, 10); 100 std::cout << "基於循環的從大到小排序:" << std::endl; 101 BubbleSort_Loop(test1, 10, greate); 102 PrintArray(test1, 10); 103 104 std::cout << "基於遞歸的從小到大排序:" << std::endl; 105 BubbleSort_Recursion(test1, 10, less); 106 PrintArray(test1, 10); 107 std::cout << "基於遞歸的從大到小排序:" << std::endl; 108 BubbleSort_Recursion(test1, 10, greate); 109 PrintArray(test1, 10); 110 111 return 0; 112 } 113 114 // 小於比較函數 115 bool less(int lhs, int rhs) 116 { 117 return lhs < rhs; 118 } 119 120 // 大於比較函數 121 bool greate(int lhs, int rhs) 122 { 123 return lhs > rhs; 124 } 125 126 // 交換兩個元素的值 127 static inline void swap(int& lhs, int & rhs) 128 { 129 int _nTemp = lhs; 130 lhs = rhs; 131 rhs = _nTemp; 132 } 133 134 // 打印數組函數 135 void PrintArray(int array[], int nLength_) 136 { 137 if (nullptr == array || nLength_ <= 0) 138 return; 139 140 for (int i = 0; i < nLength_; ++i) 141 { 142 std::cout << array[i] << " "; 143 } 144 145 std::cout << std::endl; 146 }