冒泡排序 |
通過對排序序列從前向後(從下標最小的元素開始),依次比較相鄰元素的值,若發現逆序則交換,使值較大的元素逐漸從前移到後部,就像水底下的氣泡一樣逐漸向上冒
如果一趟下來沒有進行過交換就說明序列有序,因此要在排序過程中設置一個標誌flag判斷元素是否進行過交換,從而減少不比較的比較
思路
有這樣一個數組arr {5,6,4,3,2,1},使用冒泡排序從小到大
第一趟排序:
5 6 4 3 2 1
5 4 6 3 2 1
5 4 3 6 2 1
5 4 3 2 6 1
5 4 3 2 1 6
最大的6已經交換到了最右邊
第二趟排序:
4 5 3 2 1 6
4 3 5 2 1 6
4 3 2 5 1 6
4 3 2 1 5 6
4 3 2 1 5 6
最大的5交換到6的後面
第三趟排序:
3 4 2 1 5 6
3 2 4 1 5 6
3 2 1 4 5 6
3 2 1 4 5 6
最大的4交換到5的後面
第四趟排序
2 3 1 4 5 6
2 1 3 4 5 6
2 1 3 4 5 6
最大的3交換到4的後面
第五趟排序
1 2 3 4 5 6
1 2 3 4 5 6
最大的2交換到3的後面,然後最後一次比較沒有發生交換,冒泡結束
總結:
- 冒泡排序一共進行數組元素個數-1趟交換
- 每趟排序的次數在逐漸減少
推導
聲明數組arr
根據上面的思路,第一趟交換進行了arr.length-1次,如果數組的第一個元素大於第二個元素,那麼就發生交換,代碼如下:
第二趟就只比較arr.length-2次,因爲最大的數已經被交換到最右邊了
第三趟、第四趟、第五趟都同理可得,比較的數越來越少,因爲比較的趟數
等於數組元素個數-1,所以當數組元素個數爲n時,趟數爲n-1,也就是
假設趟數爲i,只要在上面代碼外面套一層for循環,然後讓i去遞增即可,所以
最後代碼實現如下:
實現
優化
優化主要是根據思路而來,思路中,每趟排序有多次,而當有一次比較沒有發生交換,就意味着不需要再進行比較了
速度測試
增加一個80000個 數的數組
獲取當前時間
獲取排序後時間
優化之後的執行結果,13秒
註釋優化的代碼
優化之前是15秒
需要多次執行再比較,優化之後的時間大多數是要小於優化之前的時間的,這是因爲CPU有其他情況,不一定每次執行時間一致
小結
- 時間複雜度
優化之前的時間複雜是O(N²),優化之後 O(N) - 空間複雜度,就是借用了flag這個變量需要申請空間
最優的空間複雜度,同樣,就是不需要借用第三方內存空間,則複雜度爲0
最差的空間複雜度就是開始元素逆序排序,每次都要借用一次內存,按照實際的循環次數,爲O(N)
冒泡排序是穩定的,因爲每次都是相鄰的兩個兩兩交換