1. 程式人生 > 其它 >排序演算法之氣泡排序

排序演算法之氣泡排序

排序演算法之氣泡排序

簡介

氣泡排序(Bubble Sort),是一種電腦科學領域的較簡單的排序演算法。

它重複地走訪過要排序的元素列,依次比較兩個相鄰的元素,如果順序(如從大到小、首字母從Z到A)錯誤就把他們交換過來。走訪元素的工作是重複地進行直到沒有相鄰元素需要交換,也就是說該元素列已經排序完成。

這個演算法的名字由來是因為越小的元素會經由交換慢慢“浮”到數列的頂端(升序或降序排列),就如同碳酸飲料中二氧化碳的氣泡最終會上浮到頂端一樣,故名“氣泡排序”。


基本思想

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

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

(3)針對所有的元素重複以上的步驟,除了最後一個。

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


排序過程

此處排序資料:{29,10,14,37,13,14}



程式碼實現

/**
 * 氣泡排序
 * @Author distance
 */
public class BubbleSort {

    public static void sort(int[] num) {
        int temp;
        for (int i = 0; i < num.length - 1; i++) {
            for (int j = 0; j < num.length - i -1; j++) {
                if (num[j] > num[j+1]) {
                    temp = num[j];
                    num[j] = num[j+1];
                    num[j+1] = temp;
                }
            }
        }
    }

    public static void main(String[] args) {
        int[] num = {29,10,14,37,13,14};

        BubbleSort.sort(num);

        for (int i = 0; i < num.length; i++) {
            System.out.print(num[i] + " ");
        }
    }
}

程式碼優化

有沒有更優化的實現方式呢?

我們先來分析一下,結合程式碼我們發現氣泡排序有兩次for迴圈,這不是一個高效的演算法。如果說我們能夠減少冒泡的次數,則可以極大的提升演算法的執行效率。

其實我們只要結合氣泡排序演算法的核心思想後半部分:比較交換相鄰的元素。如果在一輪冒泡中,沒有發生相鄰元素的交換,那說明序列已經有序了,不管後面還剩下多少次冒泡,我們都不需要再進行冒泡下去了。這樣就減少了冒泡的次數。

關於減少冒泡次數的分析,如果你暫時沒有理解,沒有關係。請看下面的程式碼實現。

/**
 * 氣泡排序優化
 * @Author distance
 */
public class BubbleSort {

    public static void sort(int[] num) {
        int temp;
        for (int i = 0; i < num.length - 1; i++) {
            boolean flag = false;	// 設定標誌位
            for (int j = 0; j < num.length - i - 1; j++) {
                if (num[j] > num[j+1]) {
                    temp = num[j];
                    num[j] = num[j+1];
                    num[j+1] = temp;
                    flag = true;	// 交換了
                }
            }
            if (!flag) {	// 未交換,已經有序了,停止排序
                break;
            }
        }
    }

    public static void main(String[] args) {
        int[] num = {29,10,14,37,13,14};

        BubbleSort.sort(num);

        for (int i = 0; i < num.length; i++) {
            System.out.print(num[i] + " ");
        }
    }
}

演算法分析

時間複雜度

如果初始狀態已經是正序的,一趟掃描即可完成排序。所需的關鍵字比較次數為 n-1​ 次和移動次數為 0,均達到最小值。所以,氣泡排序最好的時間複雜度為 O(n)。

如果初始狀態是反序的,需要進行 n-1 趟排序。每趟排序要進行 n-i 次關鍵字的比較 (1≤i≤n-1),且每次比較都必須移動數字三次來達到交換位置。在這種情況下,比較和移動次數均達到最大值。

氣泡排序的最壞時間複雜度為 O(n^2)。

綜上,因此氣泡排序總的平均時間複雜度為 O(n^2)。


演算法穩定性

氣泡排序就是把小的元素往前調或者把大的元素往後調。比較是相鄰的兩個元素比較,交換也發生在這兩個元素之間。

所以,如果兩個元素相等,是不會再交換的;如果兩個相等的元素沒有相鄰,那麼即使通過前面的兩兩交換把兩個相鄰起來,這時候也不會交換,所以相同元素的前後順序並沒有改變。

所以氣泡排序是一種穩定排序演算法