排序演算法總結

2021-09-18 05:15:48 字數 4380 閱讀 7821

前幾天剛學完排序演算法,趁熱對所學排序演算法進行乙個總結:

就是將需要排序的元素分成兩部分,每次從右邊部分取出乙個元素往前面部分去比較排序。

最優時間複雜度: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 的演算法。快速排序 快速排序是乙個就地排序,分而治之,大規模遞迴的演算法。從本質上來...