【DS】排序算法之冒泡排序(Bubble Sort)

1、算法思想前端

    冒泡排序是排序算法中比較有意思的一種排序方法,也很簡單。其算法思想以下:算法

1)比較相鄰的元素。若是第一個比第二個大,就交換他們兩個。數組

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

3)針對全部的元素重複以上的步驟,除了最後一個。spa

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

 

2、算法示意圖blog

     這幅圖形象的展現了冒泡的過程,最左邊一列,從下往上顯示了等待排序的數列,最後一列則顯示了冒泡排序的最終結果。每一列陰影的部分表明等待排序的數列,黃色部分表示排序完成的部分,冒泡過程當中不須要涉及黃色部分,咱們解釋一下第二列的造成過程:排序

     第二列在冒泡過程當中(從下往上看),首先比較2和3,2<3,則交換;比較3和4,4>3,不須要交換;比較4和9,9>4,不須要交換,比較1和9,1<9,交換;比較5和9,5<9,交換;比較7和9,7<9,交換;比較6和9,6<9,交換;比較8和9,8<9,交換。這樣就造成了第二列。第二列造成之後,9,也就是最後的數字已是最大的了,第二趟這樣進行造成第三列的時候,就不須要進行到9了。class

     每一趟冒泡,都是將灰色數列部分中最大的數字選擇出來放到黃色部分的最下層,由此造成下一列,最大數字的選擇是經過數字的交換來完成的——算法會從數列的最前端開始日後遍歷,若是發現某一個數比它前面的數字小,就會進行交換,把較大的數字日後移動。由此不斷進行,就能夠將最大的數字移動到數列灰色部分的最後。遍歷

 

3、Java代碼

 1 //@wiki
 2 public class BubbleSort extends Sort {
 3     public static void sort(int[] array) {
 4         int temp = 0;
 5         for (int i = array.length - 1; i > 0; --i) {
 6             for (int j = 0; j < i; ++j) {
 7                 if (array[j + 1] < array[j]) {
 8                     temp = array[j];
 9                     array[j] = array[j + 1];
10                     array[j + 1] = temp;
11                 }
12             }
13         }
14     }
15 }

 

4、算法複雜度

      從上面的Java代碼來看,第7行的比較是必定會進行的,假設數組元素是n,則進行的次數是:n*(n-1)/2。由於j是從0~i-1,而i是從n-1~1,因此簡單計算就能夠得出以上的結果。

      最差的狀況固然是每次都執行if條件判斷,而且執行其中的8,9,10三行語句,總體複雜度爲4*n^2。出現最壞的狀況就是一開始數列是倒敘排列的,即按照從大到小的順序排列的,致使每一次比較都須要交換。

      在本代碼中,最好的狀況其實不能達到,咱們去看示意圖,咱們發現五列已經完成了排序,第6,7,8列的排序過程其實能夠省略。因此,冒泡排序能夠優化,咱們增長一個flag,當一趟冒泡完成時咱們發現沒有發生交換行爲,就能夠終止冒泡了,其代碼以下:

 1 public class BubbleSort extends Sort {
 2     public static void sort(int[] array) {
 3         int temp = 0;
 4         for (int i = array.length - 1; i > 0; --i) {
 5             boolean exchange = false;
 6             for (int j = 0; j < i; ++j) {
 7                 if (array[j + 1] < array[j]) {
 8                     exchange = true;
 9                     temp = array[j];
10                     array[j] = array[j + 1];
11                     array[j + 1] = temp;
12                 }
13             }
14             if(!exchange)
15                 return;
16         }
17     }
18 }

      如上,這樣,咱們能夠將最好的複雜度下降爲n,狀況出如今數列一開始就是從小到大排列的時候,只須要遍歷一邊,exchange始終爲false,直接返回,這樣就能夠獲得最好的時間複雜度,爲O(n),所以平均時間複雜度爲O(n^2)

      空間複雜度很是容易,由代碼能夠看出來,只須要一個位置temp用於交換便可,所以是O(1)

相關文章
相關標籤/搜索