1. 程式人生 > >氣泡排序+優化版

氣泡排序+優化版

轉自:https://blog.csdn.net/guoweimelon/article/details/50902597

氣泡排序(Bubble Sort)是一種典型的交換排序演算法,通過交換資料元素的位置進行排序。

一、演算法基本思想

(1)基本思想

氣泡排序的基本思想就是:從無序序列頭部開始,進行兩兩比較,根據大小交換位置,直到最後將最大(小)的資料元素交換到了無序佇列的隊尾,從而成為有序序列的一部分;下一次繼續這個過程,直到所有資料元素都排好序。

演算法的核心在於每次通過兩兩比較交換位置,選出剩餘無序序列裡最大(小)的資料元素放到隊尾。


(2)執行過程

氣泡排序演算法的運作如下:

1、比較相鄰的元素。如果第一個比第二個大(小),就交換他們兩個。

2、對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。這步做完後,最後的元素會是最大(小)的數。

3、針對所有的元素重複以上的步驟,除了最後已經選出的元素(有序)。

4、持續每次對越來越少的元素(無序元素)重複上面的步驟,直到沒有任何一對數字需要比較,則序列最終有序。


(3)示例


二、演算法實現(核心程式碼)

C++實現:

  1. void bubble_sort(int arr[], int len) {
  2. int i, j;
  3. for (i = 0; i < len - 1; i++)
  4. for
    (j = 0; j < len - 1 - i; j++)
  5. if (arr[j] > arr[j + 1])
  6. swap(arr[j], arr[j + 1]);
  7. }


Java實現:

  1. public static void bubble_sort(int[] arr) {
  2. int i, j, temp, len = arr.length;
  3. for (i = 0; i < len - 1; i++)
  4. for (j = 0; j < len - 1 - i; j++)
  5. if (arr[j] > arr[j + 1]) {
  6. temp = arr[j];
  7. arr[j] = arr[j + 1];
  8. arr[j + 1] = temp;
  9. }
  10. }


三、演算法改進和變種

(1)設定標誌變數change

標誌變數用於記錄每趟氣泡排序是否發生資料元素位置交換。如果沒有發生交換,說明序列已經有序了,不必繼續進行下去了。

  1. void bubble_sort(int arr[], int len) {
  2. int i, j, change= 1;
  3. for (i = 0; i < len - 1 && change!= 0; i++)
  4. {
  5. change= 0;
  6. for (j = 0; j < len - 1 - i; j++)
  7. if (arr[j] > arr[j + 1])
  8. {
  9. swap(arr[j], arr[j + 1]);
  10. change = 1;
  11. }
  12. }
  13. }

(2)雞尾酒排序

雞尾酒排序又叫定向氣泡排序,攪拌排序、來回排序等,是氣泡排序的一種變形。此演算法與氣泡排序的不同處在於排序時是以雙向在序列中進行排序。

雞尾酒排序在於排序過程是先從低到高,然後從高到低;而氣泡排序則僅從低到高去比較序列裡的每個元素。它可以得到比氣泡排序稍微好一點的效能,原因是氣泡排序只從一個方向進行比對(由低到高),每次迴圈只移動一個專案。

以序列(2,3,4,5,1)為例,雞尾酒排序只需要從低到高,然後從高到低就可以完成排序,但如果使用氣泡排序則需要四次。

但是在亂數序列的狀態下,雞尾酒排序與氣泡排序的效率都很差勁。

  1. void cocktail_sort(int arr[], int len) {
  2. int j, left = 0, right = len - 1;
  3. while (left < right) {
  4. for (j = left; j < right; j++)
  5. if (arr[j] > arr[j + 1])
  6. swap(arr[j], arr[j + 1]);
  7. right--;
  8. for (j = right; j > left; j--)
  9. if (arr[j - 1] > arr[j])
  10. swap(arr[j - 1], arr[j]);
  11. left++;
  12. }
  13. }


四、效能(演算法時間、空間複雜度、穩定性)分析

(1)時間複雜度

在設定標誌變數之後:

當原始序列“正序”排列時,氣泡排序總的比較次數為n-1,移動次數為0,也就是說氣泡排序在最好情況下的時間複雜度為O(n)

當原始序列“逆序”排序時,氣泡排序總的比較次數為n(n-1)/2,移動次數為3n(n-1)/2次,所以氣泡排序在最壞情況下的時間複雜度為O(n^2)

當原始序列雜亂無序時,氣泡排序的平均時間複雜度為O(n^2)


(2)空間複雜度

氣泡排序排序過程中需要一個臨時變數進行兩兩交換,所需要的額外空間為1,因此空間複雜度為O(1)


(3)穩定性

氣泡排序在排序過程中,元素兩兩交換時,相同元素的前後順序並沒有改變,所以氣泡排序是一種穩定排序演算法