我知道你會氣泡排序,那你會優化氣泡排序嗎?

2021-10-24 00:20:37 字數 3569 閱讀 6580

在生活中,我們離不開排序,比如我們上學的時候按個頭高低排位置,現在我們買東西的時候會按照發貨地遠近進行排序,或者**高低排序。

排序看著簡單,可是背後藏著很多的演算法和思想。在這給大家介紹一下常用的排序演算法。

每次提到排序,繞不開的就是氣泡排序。

氣泡排序(bubble sort)是一種基礎的交換排序。它的基本思想是:兩兩比較相鄰記錄的關鍵字,如果反序則交換,直到沒有反序的記錄為止。這個演算法的名字由來是因為越小的元素會經由交換慢慢「浮」到數列的頂端(公升序或降序排列),就如同碳酸飲料中二氧化碳的氣泡最終會上浮到頂端一樣,故名「氣泡排序」。

我們先來看乙個例子。

有這麼8個數字組成的無序數列[5,8,6,3,9,2,1,7],希望按照從小到大的順序對其進行排序。

按照氣泡排序的演算法,我們需要鏈路比較相鄰紀錄的關鍵字,如果乙個元素大於右邊相鄰元素時,交換他們的位置,當乙個元素小於或等於右邊元素,位置不變。

第一趟下來,元素9作為這個數列中最大的元素,就像是汽水裡的氣泡一樣,冒到了最右側。

再來第二趟:

第二次交換結束,8作為未排序中的最大元素被冒到右側第二位置上。

將未排序的都遍歷過之後,所有的元素都會變為有序,這就是氣泡排序的思路。

接下來,我們來實現這個**,**非常簡單,使用雙迴圈實現。內部迴圈控制每一輪的最大元素冒泡處理,外部迴圈控制所有元素的依次排序。

def bubble_sort(nums):

for i in range(len(nums) - 1): # 這個迴圈負責設定氣泡排序進行的次數

for j in range(len(nums) - i - 1):  # 內部迴圈控制每一輪的最大元素冒泡處理

if nums[j] > nums[j + 1]:

nums[j], nums[j + 1] = nums[j + 1], nums[j]

return nums

print(bubble_sort([5,8,6,3,9,2,1,7]))

我們來看看氣泡排序的基本效能:

關於穩定性:因為在比較的過程中,當兩個相同大小的元素相鄰,只比較大或者小,所以相等的時候是不會交換位置的。而當兩個相等元素離著比較遠的時候,也只是會把他們交換到相鄰的位置。他們的位置前後關係不會發生任何變化,所以演算法是穩定的。

氣泡排序是一種比較好理解的排序,但是整體的效能相比較來說比較差,因此需要進行優化。

我們來看乙個特殊情況。

如果按照上面說的演算法去進行計算,我們加一點**進去看看具體排序情況:

def bubble_sort(nums):

for i in range(len(nums) - 1): # 這個迴圈負責設定氣泡排序進行的次數

for j in range(len(nums) - i - 1): # 內部迴圈控制每一輪的最大元素冒泡處理

if nums[j] > nums[j + 1]:

nums[j], nums[j + 1] = nums[j + 1], nums[j]

print(「第」, i , 「次排序後:」, end=』』)

for n in nums:

print(n, end=』 ,』)

print(" ")

return nums

print(bubble_sort([1,3,4,5,6,7,8,9]))

實際輸出:

第 0 次排序後:1 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,

第 1 次排序後:1 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,

第 2 次排序後:1 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,

第 3 次排序後:1 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,

第 4 次排序後:1 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,

第 5 次排序後:1 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,

第 6 次排序後:1 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,

[1, 3, 4, 5, 6, 7, 8, 9]

我們能看到在第一次迴圈的時候,整個數列已經是有序的,但是常規版的演算法依然會繼續流程,浪費很多的時間,而這些都是多餘的。

如果我們能判斷出數列已經有序,並且做出標記,那麼剩下的幾輪排序就不必執行了,可以提前結束工作。我們來改良一下**:

def bubble_sort(nums):

for i in range(len(nums) - 1): # 這個迴圈負責設定氣泡排序進行的次數

#有序標記,每一輪的初始值都是true

is_sorted = true

for j in range(len(nums) - i - 1):  # 內部迴圈控制每一輪的最大元素冒泡處理
if nums[j] > nums[j + 1]:

#因為有元素進行交換,所以不是有序的,標記變為false

nums[j], nums[j + 1] = nums[j + 1], nums[j]

is_sorted = false

print(「第」, i , 「次排序後:」, end=』』)

for n in nums:

print(n, end=』 ,』)

print(" ")

if is_sorted:

break

return nums

print(bubble_sort([1,3,4,5,6,7,8,9]))

加上這個標記位之後,我們再來執行一下:
第 0 次排序後:1 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,

[1, 3, 4, 5, 6, 7, 8, 9]

可以看到,當整體數列已經有序的基礎上,不需要再進行後續的多次排序時間浪費了。整體的最好時間就優化為o(n)。

最後祝大家學習愉快。

作  者:testfan chris

氣泡排序 氣泡排序演算法優化

常用的排序演算法主要包括 1 插入排序 直接插入排序 希爾排序 2 交換排序 氣泡排序 快速排序 3 選擇排序 簡單選擇排序 堆排序快速排序 4 歸併排序其中,氣泡排序算是最簡單的一種排序演算法 public class bubble int temp 0 for int i 0 iarr j 1 ...

C 氣泡排序 氣泡排序的優化

本文包含氣泡排序的三種實現方式 分別為氣泡排序初級版,公升級版,終級版 自己起的名字 使用時只要使用終極版就本以了,終級版為公升級版的優化版本 至於初極版和公升級版只是為了幫助理解 氣泡排序的時間複雜度為o n include include include include include incl...

氣泡排序以及氣泡排序的優化

很早接觸過氣泡排序法,但一直沒有真正的理解,只是為了記住而學習,今天又重新看了一下,其實氣泡排序法第一次排序會把最大的冒到最上面,第二次會把次大的泡冒到最大的後面,一次類推 另外在排序的次數上會逐漸減少。看 void bubble sort int a,int n 其實還可以優化一下,當發現沒有進行...