python資料結構與演算法(15)
選擇排序
選擇排序(Selection sort)是⼀種簡單直觀的排序演算法。它的⼯作原理如 下。⾸先在未排序序列中找到最⼩(⼤)元素,存放到排序序列的起始位 置,然後,再從剩餘未排序元素中繼續尋找最⼩(⼤)元素,然後放到已排 序序列的末尾。以此類推,直到所有元素均排序完畢。
選擇排序的主要優點與資料移動有關。如果某個元素位於正確的最終位置 上,則它不會被移動。選擇排序每次交換⼀對元素,它們當中⾄少有⼀個將 被移到其最終位置上,因此對n個元素的表進⾏排序總共進⾏⾄多n-1次交 換。在所有的完全依靠交換去移動元素的排序⽅法中,選擇排序屬於⾮常好 的⼀種。
選擇排序分析
排序過程:
紅⾊表示當前最⼩值,⻩⾊表示已排序序列,藍⾊表示當前
位置。
def selection_sort(alist): n = len(alist) # 需要進⾏n-1次選擇操作 for i in range(n-1): # 記錄最⼩位置 min_index = i # 從i+1位置到末尾選擇出最⼩資料 for j in range(i+1, n): if alist[j] < alist[min_index]: min_index = j # 如果選擇出的資料不在正確位置,進⾏交換 if min_index != i: alist[i], alist[min_index] = alist[min_index], al ist[i] alist = [54,226,93,17,77,31,44,55,20] selection_sort(alist) print(alist)
時間複雜度
最優時間複雜度:O(n ) 最壞時間複雜度:O(n ) 穩定性:不穩定(考慮升序每次選擇最⼤的情況)
選擇排序演示
插⼊排序
插⼊排序(英語:Insertion Sort)是⼀種簡單直觀的排序演算法。它的⼯作原 理是通過構建有序序列,對於未排序資料,在已排序序列中從後向前掃描, 找到相應位置並插⼊。插⼊排序在實現上,在從後向前掃描過程中,需要反 復把已排序元素逐步向後挪位,為最新元素提供插⼊空間。
插⼊排序分析
def insert_sort(alist): # 從第⼆個位置,即下標為1的元素開始向前插⼊ for i in range(1, len(alist)): # 從第i個元素開始向前⽐較,如果⼩於前⼀個元素,交換位置 for j in range(i, 0, -1): if alist[j] < alist[j-1]: alist[j], alist[j-1] = alist[j-1], alist[j] alist = [54,26,93,17,77,31,44,55,20] insert_sort(alist) print(alist)
時間複雜度
最優時間複雜度:O(n) (升序排列,序列已經處於升序狀態) 最壞時間複雜度:O(n ) 穩定性:穩定
插⼊排序演示
快速排序
快速排序(英語:Quicksort),⼜稱劃分交換排序(partition-exchange sort),通過⼀趟排序將要排序的資料分割成獨⽴的兩部分,其中⼀部分的 所有資料都⽐另外⼀部分的所有資料都要⼩,然後再按此⽅法對這兩部分數 據分別進⾏快速排序,整個排序過程可以遞迴進⾏,以此達到整個資料變成 有序序列。
步驟為:
- 從數列中挑出⼀個元素,稱為"基準"(pivot), 2. 重新排序數列,所有元素⽐基準值⼩的擺放在基準前⾯,所有元素⽐基 準值⼤的擺在基準的後⾯(相同的數可以到任⼀邊)。在這個分割槽結束 之後,該基準就處於數列的中間位置。這個稱為分割槽(partition)操作。 3. 遞迴地(recursive)把⼩於基準值元素的⼦數列和⼤於基準值元素的⼦ 數列排序。
遞迴的最底部情形,是數列的⼤⼩是零或⼀,也就是永遠都已經被排序好 了。雖然⼀直遞迴下去,但是這個演算法總會結束,因為在每次的迭代 (iteration)中,它⾄少會把⼀個元素擺到它最後的位置去。
快速排序的分析
def quick_sort(alist, start, end): """快速排序""" # 遞迴的退出條件 if start >= end: return # 設定起始元素為要尋找位置的基準元素 mid = alist[start] # low為序列左邊的由左向右移動的遊標 low = start # high為序列右邊的由右向左移動的遊標 high = end while low < high: # 如果low與high未重合,high指向的元素不⽐基準元素⼩,則high向 左移動 while low < high and alist[high] >= mid: high -= 1 # 將high指向的元素放到low的位置上 alist[low] = alist[high] # 如果low與high未重合,low指向的元素⽐基準元素⼩,則low向右移動 while low < high and alist[low] < mid: low += 1 # 將low指向的元素放到high的位置上 alist[high] = alist[low] # 退出迴圈後,low與high重合,此時所指位置為基準元素的正確位置 # 將基準元素放到該位置 alist[low] = mid # 對基準元素左邊的⼦序列進⾏快速排序 quick_sort(alist, start, low-1) # 對基準元素右邊的⼦序列進⾏快速排序 quick_sort(alist, low+1, end) alist = [54,26,93,17,77,31,44,55,20] quick_sort(alist,0,len(alist)-1) print(alist)