氣泡排序與選擇排序

2021-07-10 15:54:14 字數 2463 閱讀 7234

氣泡排序(bubble sort):

輸入:亂序n長陣列

輸出:排序好的n長陣列

時間複雜度:o(n^2)

空間複雜度:o(1)

氣泡排序的原理是對陣列多次掃瞄,每次掃瞄都對相鄰的兩個元素的順序進行調整。假設我們按公升序排列陣列,那麼相鄰兩個元素中如果左邊的元素大於右邊的元素,就交換這兩個元素位置,否則不交換。依次掃瞄過陣列中全部元素。可見第一次掃瞄就使得陣列的最大值排在了陣列的最後乙個位置,第二次掃瞄使得陣列中第二大的元素排在了陣列的倒數第二個位置。。。以此類推。這樣,最多需要進行n-1次掃瞄就能完成排序。我們來看乙個具體的例子:

陣列[6, 5, 3, 1, 8, 7, 2, 4]的第一次掃瞄過程如下:

6>5:交換位置->[5, 6, 3, 1, 8, 7, 2, 4]

6>3:交換位置->[5, 3, 6, 1, 8, 7, 2, 4]

6>1:交換位置->[5, 3, 1, 6, 8, 7, 2, 4]

6<8:不交換->[5, 3, 1, 6, 8, 7, 2, 4]

8>7:交換位置->[5, 3, 1, 6, 7, 8, 2, 4]

8>2:交換位置->[5, 3, 1, 6, 7, 2, 8, 4]

8>4:交換位置->[5, 3, 1, 6, 7, 2, 4, 8]

可以看出,經過第一次掃瞄,陣列的最大值8移動到了陣列的最後乙個位置,掃瞄的過程就是依次比較相鄰元素的大小,再做交換。大的元素像氣泡一樣最終「公升至」陣列「頂端」。

同理,第二次掃瞄我們只需要對陣列的前n-1個元素做相同的掃瞄即可,使得前n-1個元素的最大值(也就是整個陣列的第二大元素)排在陣列的倒數第二的位置。

可見,最多隻需要n-1次掃瞄就能排列整個陣列。這裡,之所以說「最多」,是因為,假如第x次掃瞄沒有發生元素交換位置(也就是說當前所掃瞄的陣列是排好序的),那麼,很顯然,我們當然沒有必要再進行之後的掃瞄。乙個簡單的例子是:陣列[2, 1, 3, 4],經過第一次掃瞄,變成[1, 2, 3, 4];第二次掃瞄沒有發生元素交換,說明已經排好序,就沒有必要再進行第三次掃瞄了。

**可以這樣寫:

def bubble_sort(alist):

# 用bool值next判斷是否還需要進行下一輪掃瞄

next = true

n = len(alist)

while next:

next = false

for i in range(0, n - 1):

if alist[i] > alist[i + 1]:

# 交換位置

alist[i], alist[i + 1] = alist[i + 1], alist[i]

next = true

n -= 1

其中,布林變數next用來判斷是否需要進行下一輪掃瞄。第11行是python常見的交換陣列中兩元素位置的寫法。這個函式只是對陣列原地排序,沒有返回值。

選擇排序(selection sort):

輸入:亂序n長陣列

輸出:排序好的n長陣列

時間複雜度:o(n^2)

空間複雜度:o(1)

從原理上講,選擇排序與氣泡排序是一樣的,都是通過掃瞄陣列找出陣列的「最值」,然後將這些挑選出的元素依次排列。不同的是,冒泡是通過比較相鄰元素的方法選出最大值,而選擇排序是用更「簡單粗暴」的方式選出最小值,將每次選出的最小值依次排列,從而完成排序。

舉個簡單例子:陣列[3, 2, 1]。經過第一次掃瞄「選擇」出最小值1,與陣列的首元素3交換位置,變成[1, 2, 3],之後第二次掃瞄陣列[2, 3]部分(顯然,第乙個元素已經安置好,不用掃瞄了),"選擇"出[2, 3]部分最小元素(也是整個陣列第二小元素)2,與2交換位置(這裡是它本身,相當於不交換)。對於這個有三個元素的陣列而言,需經過兩次掃瞄,這一點與氣泡排序一樣,都是對於n長陣列需要進行n-1次排序,大家也就可以通過這一點計算出時間複雜度(過程我略了)。

那麼,思路很清楚了,我們就能寫出**:

def selection_sort(alist):

begin = 0

n = len(alist)

# begin表示開始掃瞄的位置,也是放置每次選出的最小值的位置

while begin < n - 1:

# min_index代表最小值所在的位置

min_index = begin

for i in range(begin, n):

if alist[i] < alist[min_index]:

min_index = i

# 交換位置

alist[begin], alist[min_index] = alist[min_index], alist[begin]

begin += 1

這裡,一樣是個沒有返回值的函式。其實,這兩種排序演算法都不難,但是細節處還是得搞清楚,否則,也不容易一遍就寫對。

下一節,我們就來看看另一種排序方法:插入排序

排序 氣泡排序與選擇排序

最近複習大學學過的演算法,這裡做個筆記。排序,我們學過 這裡需要了解什麼是時間複雜度,什麼是空間複雜度。簡單而言,時間複雜度指執行的次數,空間複雜度指消耗的記憶體。它重複地走訪過要排序的元素列,依次比較兩個相鄰的元素,如果順序 如從大到小 首字母從z到a 錯誤就把他們交換過來。走訪元素的工作是重複地...

選擇排序與氣泡排序

今早心血來潮,又想看看氣泡排序.於是乎度娘一番,找到了度娘給我的這篇文章,前面的文字描述還是簡單易懂的,可惜給出的 示範有些文不對題.於是乎又wiki一番.發現上文給出的 形似選擇排序,於是總結如下 我們假設有乙個陣列 624159 對應的索引也就是 0 5,如果我想描述第二個位置,也就是數字2的位...

選擇排序與氣泡排序

選擇排序 static void sort1 int arr var temp arr i arr i arr min arr min temp 氣泡排序 static void sort2 int arr static void main string args sort1 arr foreach...