Python經典排序算法
http://www.rzrgm.cn/onepixel/p/7674659.html這個文章很nice
https://www.bilibili.com/video/av685670?from=search&seid=1637373535603658338這個動圖優秀
https://www.icourse163.org/course/ZJU-93001 MOOC浙大 數據結構 陳越、何欽銘
VisuAlgo - visualising data structures and algorithms through animation 數據結構與算法的可視化網站 更容易讓人感性理解各種算法
冒泡排序、選擇排序、插入排序這三個是最慢也是最經典的三個排序算法
快速排序對于大的亂數串列一般相信是最快的已知排序
冒泡排序 bubble sort
最簡單的排序算法,也是效率最差的,因為它必須在最終位置知道前交換,浪費許多“交換操作”
如果列表已經排序,則是最好情況,遍歷期間無需交換,如果發現已經排序,可以提前終止,這種修改下的冒泡通常稱為短冒泡排序
時間復雜度: 平均O(n^2) 最差O(n^2) 最好O(n)
空間復雜度:O(1)
穩定
#測試輸入數組
alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14]
#冒泡排序
for i in range(len(alist)-1):
for j in range(len(alist)-1-i):
if alist[j] > alist[j+1]:
alist[j],alist[j+1] = alist[j+1],alist[j]
#排序結果輸出
print('sorted:',alist)
選擇排序 selection sort
選擇排序改進了冒泡排序,每次遍歷列表只做一次交換
時間復雜度:平均O(n^2) 最差O(n^2) 最好O(n^2)
空間復雜度:O(1)
不穩定
#測試輸入數組
alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14]
#選擇排序
for i in range(len(alist)-1):
least = i
for j in range(i+1,len(alist)):
if alist[j] < alist[least]:
least = j
if least != i:
alist[least],alist[i] = alist[i],alist[least]
#排序結果輸出
print('sorted:',alist)
插入排序 insertion sort
它始終在列表的較低位置維護一個排序的子列表,然后將每個新項 “插入” 回先前的子列表,使得排序的子列表成為較大的一個項
時間復雜度: 平均O(n^2) 最差O(n^2) 最好O(n)
空間復雜度:O(1)
穩定
#測試輸入數組
alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14]
#插入排序
for i in range(1,len(alist)):
j = i;
while j>0 and alist[j-1]>alist[j]:
alist[j-1],alist[j] = alist[j],alist[j-1]
j -= 1
#排序結果輸出
print('sorted:',alist)
希爾排序 shell sort
是1959年Shell發明,第一個突破O(n^2)的排序,是對簡單插入排序的改進,與插入排序不同的是它優先比較距離較遠的元素,又叫“遞減增量排序”
是針對插入排序以下2特點改進:在對幾乎已經排好序的數據操作時,效率高,即可以達到線性排序的效率;一般來說是低效的,因為插入排序每次只能將數據移動一位
希爾排序通過將比較的全部元素分為幾個區域來提升插入排序的性能。這樣可以讓一個元素可以一次性地朝最終位置前進一大步
gap概念,gap遞減,最后一步就是插入排序,但是此時幾乎已經排好序了
gap是希爾排序核心
出名的gap設置Marcin Ciura's gap sequence ,gaps = [701, 301, 132, 57, 23, 10, 4, 1],不過下面例子用數組長度不斷整除2得到的序列作為gaps
時間復雜度:平均O(n(logn)^2) 最差O(n^2) 最好O(n)
空間復雜度:O(1)
不穩定
#測試輸入數組
alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14]
#希爾排序
gap = len(alist)//2
while gap>0:
#對每個gap做插入排序
for i in range(gap,len(alist)):
j = i
while j>=gap and alist[j-gap]>alist[j]:
alist[j-gap],alist[j] = alist[j],alist[j-gap]
j -= gap
gap = gap//2
#排序結果輸出
print('sorted:',alist)
歸并排序 merge sort
分而治之的策略來提高性能,是分治法的典型應用
歸并排序是一種遞歸算法,不斷將列表拆分為一半
二路歸并 多路歸并
缺點是在合并過程需要額外存儲空間
時間復雜度: 平均O(nlogn) 最差O(nlogn) 最好O(nlogn)
空間復雜度:O(n)
穩定
#測試輸入數組
alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14]
#歸并排序
def merge_sort(ilist):
def merge(left, right):
result = []
while left and right:
result.append((left if left[0] <= right[0] else right).pop(0))
return result + left + right
if len(ilist) <= 1:
return ilist
mid = len(ilist) // 2
return merge(merge_sort(ilist[:mid]), merge_sort(ilist[mid:]))
#排序結果輸出
print('sorted:',merge_sort(alist))
快速排序 quick sort
與歸并排序相同,采用分治法,而不使用額外存儲
是對冒泡排序的改進
通常明顯比其他算法更快,因為它的內部循環可以在大部分的架構上很有效的達成
簡單的版本和歸并排序一樣不好,需要額外存儲空間,但是可以改為in-place版本,也就不要額外空間了
時間復雜度: 平均O(nlogn) 最差O(n^2) 最好O(nlogn)
空間復雜度:O(nlogn)
不穩定
#測試輸入數組
alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14]
#快速排序
def quick_sort(ilist):
length = len(ilist)
if length <= 1:
return ilist
else:
# Use the last element as the first pivot
pivot = ilist.pop()
# Put elements greater than pivot in greater list
# Put elements lesser than pivot in lesser list
greater, lesser = [], []
for element in ilist:
if element > pivot:
greater.append(element)
else:
lesser.append(element)
return quick_sort(lesser) + [pivot] + quick_sort(greater)
#排序結果輸出
print('sorted:',quick_sort(alist))
堆排序 heap sort
是對選擇排序的一種改進
利用堆這種數據結構所設計的算法 近似完全二叉樹
堆通常通過一維數組實 大根堆 小根堆
時間復雜度:平均O(nlogn) 最差O(nlogn) 最好O(nlogn)
空間復雜度:O(1)
不穩定
#測試輸入數組
alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14]
#堆排序
def heapify(unsorted, index, heap_size):
largest = index
left_index = 2 * index + 1
right_index = 2 * index + 2
if left_index < heap_size and unsorted[left_index] > unsorted[largest]:
largest = left_index
if right_index < heap_size and unsorted[right_index] > unsorted[largest]:
largest = right_index
if largest != index:
unsorted[largest], unsorted[index] = unsorted[index], unsorted[largest]
heapify(unsorted, largest, heap_size)
def heap_sort(unsorted):
n = len(unsorted)
for i in range(n // 2 - 1, -1, -1):
heapify(unsorted, i, n)
for i in range(n - 1, 0, -1):
unsorted[0], unsorted[i] = unsorted[i], unsorted[0]
heapify(unsorted, 0, i)
return unsorted
#排序結果輸出
print('sorted:',heap_sort(alist))
博客出處:http://www.rzrgm.cn/yongestcat/
歡迎轉載,轉載請標明出處。
如果你覺得本文還不錯,對你的學習帶來了些許幫助,請幫忙點擊右下角的推薦

浙公網安備 33010602011771號