# 通常的冒泡排序
假設按照升序排序。
排序思想:
第一趟排序:首先將第一個元素和第二個元素比較,若第一個元素大于第二個元素,交換它們,然后比較第二個元素和第三個元素,……,知道第n-1個元素和第n個元素比較, 第一趟排序將最大的元素放在了最后一位(第n位);
第二趟排序:對前n-1個元素元素執行同樣操作,其結果是將第二大的元素放在了數組第n - 1的位置上。
第i趟排序:依次比較前n - i + 1個元素,將這n - i + 1個元素中最大的元素放到第n - i + 1位上。
設數組大小為n;比較相鄰的兩個數,如果第一個大于第二個,則交換兩個數據;這樣,第一個排序后,比較了n-1次,最大的數在數組末尾。然后n = n- 1,在n不為0情況下繼續排序,否則排序完成。
~~~
void bubble_sort1(int a[], int size) {
int i;
for (i = 0; i < size; ++i) {
int j;
for (j = 1; j < size - i; ++j) {
if (a[j - 1] > a[j]) {
int temp = a[j - 1];
a[j - 1] = a[j];
a[j] = temp;
}
}
}
}
~~~
# 改進版本
設置一個標記flag,如果某次排序發生了交換flag為真;否則flag為假,排序結束。排序結束的標志是某趟排序沒有發生交換。那么排序所需要的趟數k范圍是1 <= k < n。若初始序列為有序的,則只需要一趟排序,在排序過程中進行n -1 次的關鍵字的比較,且不需要移動元素。若初始序列為逆序的,則需要n - 1趟排序,共需要n(n - 1) / 2次比較,并作等數量級的元素移動。
~~~
void bubble_sort2(int a[], int size) {
int k;
bool flag;
k = size;
flag = true;
while (flag) {
flag = false;
int j;
for (j = 1; j < k; j++) {
int temp;
if (a[j - 1] > a[j]) {
temp = a[j - 1];
a[j - 1] = a[j];
a[j] = temp;
flag = true;
}
}
k--;
}
}
int main() {
int a[] = {9,4,2,6,1, 1, 1};
cout << sizeof(a) / sizeof(int) << endl;
bubble_sort1(a, sizeof(a) / sizeof(int));
//bubble_sort1(a, sizeof(a) / sizeof(int));
int i;
for (i = 0; i < sizeof(a) / sizeof(int); ++i)
cout << a[i] << " ";
cout << endl;
return 0;
}
~~~
該排序算法用到了交換兩個數的函數。參考[這里](http://blog.csdn.net/u013074465/article/details/44342629)查看面試題“不借助其他變量,交換兩個數”。
- 前言
- Josephus約瑟夫問題及其變種
- 鏈表的常見實現
- 二叉樹遍歷、插入、刪除等常見操作
- 二叉堆的插入刪除等操作C++實現
- 插入排序和希爾排序
- 堆排序
- 歸并排序及其空間復雜度的思考
- 快速排序的幾種常見實現及其性能對比
- 紅黑樹操作及實現
- 整數的二進制表示中1的個數
- 位操作實現加減乘除四則運算
- 冒泡排序的改進
- 直接選擇排序
- 不借助變量交換兩個數
- 基礎排序算法總結
- AVL樹(Adelson-Velskii-Landis tree)
- avl樹的C++實現
- 動態規劃之鋼條分割
- hash函數的基本知識
- 動態規劃:求最長公共子串/最長公共子序列
- 最長遞增子序列
- 稱砝碼問題
- 汽水瓶
- 字符串合并處理(二進制位的倒序)
- 動態規劃:計算字符串相似度
- m個蘋果放入n個盤子
- 生成k個小于n的互不相同的隨機數
- 棧和隊列的相互模擬
- 字符串的排列/組合
- KMP(Knuth-Morris-Pratt)算法
- n個骰子的點數
- 位運算的常見操作和題目