氣泡排序(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...