前幾天剛學完排序演算法,趁熱對所學排序演算法進行乙個總結:
就是將需要排序的元素分成兩部分,每次從右邊部分取出乙個元素往前面部分去比較排序。
最優時間複雜度:o(n)
最壞時間複雜度:o(n2)
穩定性:穩定
**實現:
def insert_sort(alist):
n = len(alist) #首先計算序列的長度
for i in range(1,n): #遍歷整個序列,從第二個開始,因為第乙個要用來比較
for j in range(i,0,-1): #從第二個開始往前面去比較,小的放前面。
if alist[j] 選擇排序和插入排序有點類似,插入是每次從後面序列選出乙個數,插入到左邊序列,依次比較大小。選擇排序是從左到右,依次選出最小的那個數放到最左邊。
最優時間複雜度:o(n2)
最壞時間複雜度:o(n2)
穩定性:不穩定
**實現:
def select_sort(alist):
n = len(alist):
for i in range(0,n-1):
min_index = i #假設當前這個數是最小的數
for j in range(i+1,n): #從當前數的下一位開始往後去遍歷所有位,找到最小值,把索引賦給min_index。
if alist[min_index] > alist[j]: #尋找最小的索引,賦給min_index
min_index = j
alist[min_index],alist[i] = alist[i],alist[min_index] #將最小值放到最前面,走n-1次就行啦
if __name__ == '__main__':
a = [1, 23, 4, 32, 1, 23, 432, 12, 32]
select_sort(a)
print(a)
執行結果:
[1, 1, 4, 12, 23, 23, 32, 32, 432]
從頭到尾,兩個相鄰的元素依次比較,哪個大就拿哪個往後移。
最優時間複雜度:o(n)
最壞時間複雜度:o(n2)
穩定性:穩定
**實現:
def bubble_sort(alist):
n = len(alist)
for i in range(0,n-1): # 從頭到尾比較n-1次
for j in range(0,n-i-1): # 每次少乙個數就會少比較一次
if alist[j] > alist[j+1]: #後者比前者小,就交換位置。
alist[j],alist[j+1] = alist[j+1],alist[j]
if __name__ == '__main__':
a = [1, 23, 4, 32, 1, 23, 432, 12, 32]
bubble_sort(a)
print(a)
執行結果:
[1, 1, 4, 12, 23, 23, 32, 32, 432]
歸併排序,首先對序列進行二分處理,然後再排序組合。
最優時間複雜度:o(nlogn)
最壞時間複雜度:o(nlogn)
穩定性:穩定
**實現:
def merge_sort(alist):
n = len(alist)
if n <= 1:
return alist
mid = n // 2
left_li = merge_sort(alist[:mid])
right_li = merge_sort(alist[mid:])
left_pointer, right_pointer = 0,0
result =
while left_pointer < len(left_li) and right_pointer < len(right_li):
if left_li[left_pointer] > right_li[right_pointer]:
right_pointer += 1
else:
left_pointer += 1
result += left_li[left_pointer:]
result += right_li[right_pointer:]
return result
if __name__ == '__main__':
a = [1, 23, 4, 32, 1, 23, 432, 12, 32,9,8]
c = merge_sort(a)
print(c)
執行結果:
[1, 1, 4, 8, 9, 12, 23, 23, 32, 32, 432]
序列左右兩邊準備兩個游標,往中間夾,終止條件是左邊游標比右邊游標小,左邊元素要比基準元素小,右邊元素要比基準元素大。不滿足條件就要停下,如果兩個游標都停下了,就交換位置,繼續走。
最好時間複雜度:o(nlog(n))
最壞時間複雜度:o(n2)
不穩定
**實現:
def quick_sort(alist,start,end):
#遞迴的退出條件
if start >= end:
return
#設定起始元素為要尋找位置的基準元素
mid = alist[start]
#low為序列左邊的由左向右移動的游標
low = start
#high為序列右邊的由右向左移動的游標
high = end
while low < 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
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)
它對乙個序列,取了乙個gap的步長。然後呢,用gap將這個序列分成了很多組,然後就是每組進行插入排序。
最優時間複雜度:根據選擇步長不同而不同
最壞時間複雜度:o(n2)
穩定性: 不穩定
def shell_sort(alist):
n = len(alist) #拿到整個序列的長度
gap = n // 2 #首先選出整個序列的gap,取中間值
while gap>0: #這時候我們的gap需要進行遍歷,每次取半
for j in range(gap,n): #從gap到n我們要每個元素都要比較
i = j
while i > 0: #這裡為了給每個gap分組後的序列排序時準備的終止條件
if alist[i] < alist[i -gap]: #如果後者比前者小,就要交換位置
alist[i],alist[i-gap] = alist[i-gap],alist[i] #交換位置
i -= gap #每次交換完位置後,就要往前移動gap間隔
else: #如果當前位置的值比前者大,不需要移動
break
gap = gap // 2 #遍歷的時候每次都取半
if __name__ == '__main__':
a = [1, 23, 4, 32, 1, 23, 432, 12, 32,9,8]
shell_sort(a)
print(a)
執行結果:
[1, 1, 4, 8, 9, 12, 23, 23, 32, 32, 432]
排序演算法總結
1 直接插入排序 1 穩定性 穩定 2 適用情況 待排記錄規模較小,或者記錄已經基本有序 2 希爾排序 1 穩定性 不穩定 2 特點 希爾排序的執行時間依賴於增量序列,它的效率比直接插入排序有較大的改進。3 氣泡排序 1 穩定性 穩定 2 特點 當待排記錄基本有序是,氣泡排序是不錯的選擇 但由於氣泡...
排序演算法總結
1 選擇排序 選擇排序的思想是依次從待排序數列中選擇最大 小 的 第二大 小 的等等,然後依次重新排列為有序數列。void selectionsort int a,int n if min i 時間複雜度o n 2 2 歸併排序 void merge int a,int left,int mid,i...
排序演算法總結
學習了這麼多的排序演算法,還沒有做個總結,呵呵 氣泡排序 氣泡排序是最慢的排序演算法。在實際運用中它是效率最低的演算法。它通過一趟又一趟地比較陣列中的每乙個元素,使較大的資料下沉,較小的資料上公升。它是 o n 2 的演算法。快速排序 快速排序是乙個就地排序,分而治之,大規模遞迴的演算法。從本質上來...