氣泡排序演算法是一種基於比較的排序演算法,每次冒泡過程,都會有乙個資料確定位置。經過n次冒泡後,就有n個資料確定了位置。
如圖所示,對陣列[4,5,6,3,2,1]進行氣泡排序。
* 氣泡排序演算法
* @param arr
* @param n
*/public static void bubblesort(int arr,int n)}}
}拿陣列[1,2,3,4,5,6]為例,這個比較極端完全是有序的,其實只需要一次冒泡就完成了,沒有必要迭代n次,所以這個演算法還可以改進,技巧就是當某次冒泡完全沒有引起資料交換的時候,說明這個陣列已經是有序了,程式即可退出了。
/**
* 改進後氣泡排序演算法
* @param arr
* @param n
*/public static void fixbubblesort(int arr,int n)
}if(!ischange)}}
所謂原地排序演算法,就是空間複雜度為o(1)的演算法,那麼上邊的演算法不牽涉額外得到其他空間。所以是原地排序演算法。
所謂穩定,指的是當陣列**現相同數值元素的時候,排序是否會造成相同數值元素相對位置的改變。可以看出在氣泡排序演算法中,對於相同數值的元素我們並沒有進行比較和交換位置,所以相同數值元素的相對位置不會發生改變,因此氣泡排序演算法是穩定的排序演算法。
在完全有序的情況下,最好的時間複雜度是o(n),只需要1次冒泡。而在極端情況完全逆序,時間複雜度為o(n^2).
那麼平均時間複雜度是多少?如果用概率論計算的話會非常複雜,這裡介紹的是一種粗略估計的演算法,牽涉到兩個概念
有序度和逆序度。
陣列中具有有序關係的元素對的個數。有序元素對的定義:如果i
問題:[4,5,6,3,2,1]的有序對有哪些?
答:(4,5)、(5,6)、(4,6),所以有序度為3.
問題:[6,5,4,3,2,1]的有序對有哪些?
答:不存在,所以有序度為0.
問題:[1,2,3,4,5,6]的有序對有哪些?
答:(1,2)、(1,3)、(1,4)、(1,5)、(1,6)、(2,3)、(2,4)、(2,5)、(2,6)、(3,4)、(3,5)、(3,6)、(4,5)、(4,6)、(5,6),所以有序度為15,也就是n(n-1)/2,這就是完全有序時滿有序度的計算公式。
陣列中具有逆序關係的元素對的個數。逆序元素對的定義:如果ia[j]
【 有序度 + 逆序度 =滿有序度】
其實,排序就是增加有序度的過程,一直到有序度等於滿有序度,而逆序度為0.
排序過程每交換一次,有序度加1,逆序度減1,比如剛開始原陣列的有序度為x,那麼逆序度=n(n-1)/2-x.也就是最終有序需要交換的次數。如果初始有序度x=0,那就是最壞的情況,逆序度為n(n-1)/2;如果有序度x為n(n-1)/2,那這就是最好的情況,逆序度為0,根本不需要交換。因此,可以取乙個初始有序度不好也不壞的情況x=n(n-1)/4,最終交換的次數,即逆序度就等於n(n-1)/4,換算成時間複雜度就是o(n^2).
氣泡排序的時間複雜度
氣泡排序是一種用時間換空間的排序方法,最壞情況是把順序的排列變成逆序,或者把逆序的數列變成順序。在這種情況下,每一次比較都需要進行交換運算。舉個例子來說,乙個數列 5 4 3 2 1 進行冒泡公升序排列,第一次大迴圈從第乙個數 5 開始到倒數第二個數 2 結束,比較過程 先比較5和4,4比5小,交換...
氣泡排序 時間複雜度與空間複雜度
外迴圈是遍歷每個元素,每次都放置好乙個元素 內迴圈是比較相鄰的兩個元素,把大的元素交換到後面 等到第一步中迴圈好了以後也就說明全部元素排序好了 實現 include 列印陣列元素 void print array int array,int length printf n n void bubble...
O N 時間複雜度的排序演算法 計數排序
比較排序中,氣泡排序,插入排序,堆排序,歸併排序,快速排序等都比較常見。其中快速排序的平均效能是最好的時間複雜度為n lgn 已經有證明 任意乙個比較演算法的在最壞的情況下,都需要做 n lgn 次比較。還有一種很有趣的排序演算法可以在o n 時間內完成特定序列的排序,那就是計數排序。特定條件所有整...