《面試之排序演算法效能比較》

2021-08-10 12:38:02 字數 3455 閱讀 2558

效能穩定

平均時間複雜度為 o(nlogn)

最好時間複雜度為 o(nlogn)

最壞時間複雜度為 o(nlogn)

核心思想:

(1) 分:只要可以分,就可以將list中的元素分成兩半,直到不能分則跳出

(2) 比:對於傳入兩個list,則要比較排序,則為了提高效率,輸入為有序list,

(3) 合:對於輸入兩個有序的list ,輸出為乙個有序的list.

(4) 迭代:每次分比合得出的結果 都要迭代,直到全部輸出

def

mergersort

(list):

"list的拆分"

if len(list) <= 1 :

return list

else:

num = int(len(list)/2)

"核心:分成的兩部分也要繼續分下去,所以這裡是"

"拆分函式的迭代,直到list的分解長度為1"

left = mergersort(list[:num])

right = mergersort(list[num:])

return merge(left,right)

defmerge

(left,right):

"將兩個list中的元素排序"

i ,j = 0, 0

result =

while i < len(left) and j < len(right):

if left[i] >= right[j]:

j += 1

else:

i += 1

"核心:當跳出while迴圈時,說明乙個list已經全部加入result"

"其餘元素可以直接加入result,這個使用切片,切片是支援超出index的部分的"

"如:l= [1,2] l[3:] = "

result += left[i:]

result += right[j:]

return result

快速排序 效能不穩定

平均時間複雜度 o(nlogn)

最好時間複雜度 o(nlogn)

最差時間複雜度 o(n2)

核心思想 :

每一次迴圈會有選擇乙個key,從list尾處迴圈找比key小元素位置j,並將放置在i位置

從list頭找比key大的放置在j 位置,

import numpy as np

defquicksort

(lis,low,high):

i = low

j = high

if i >= j:

return lis

# if 部分是核心部分

# 後半部分迭代的時候的跳出條件就是i>=j,否則是沒法跳出的"

key = lis[i]

# 注意 key= list[i] 一定在 跳出條件後面,否則

while i < j :

while i < j and lis[j] >= key:

j -= 1

lis[i] = lis[j]

while i < j and lis[i] <= key:

i += 1

lis[j] = lis[i]

lis[i] = key

"每一次迴圈while都是把list分成兩部分,左面是比key小的元素,右邊是比key大的元素"

quicksort(lis,low,i-1)

quicksort(lis,j+1,high)

return lis

if __name__ == '__main__':

lis = np.random.randint(1,1000,10)

lis_ = list(lis)

print lis_

low_ = 0

high_ = len(lis_) - 1

print quicksort(lis_,low_,high_)

執行結果

[44, 514, 266, 369, 215, 398, 727, 835, 939, 378]

[44, 215, 266, 369, 378, 398, 514, 727, 835, 939]

import numpy as np

# 大頂堆,從小到大排序

defcreateheap

(lis,size):

for i in range(size/2)[::-1]:

adjust_heap(lis,i,size)

defadjust_heap

(lis,i,size):

# 因為i是中心得點靠左邊的乙個點,保證了它是最後乙個根節點

lchild = 2*i + 1

rchild = 2*i + 2

max = i

if i < size/2:

if lchild < size and lis[lchild] > lis[max] :

max = lchild

if rchild < size and lis[rchild] > lis[max] :

max = rchild

if max != i:

# 則將最大值和該根節點交換位置

lis[max] , lis[i] = lis[i], lis[max]

# 調整了乙個位置則需要將其子樹進行重新堆排序

adjust_heap(lis,max,size)

if __name__ == "__main__" :

#lis = [1,3,9,0,2,8,5,6]

lis_ = np.random.randint(1,1000,10)

lis = list(lis_)

size = len(lis)

createheap(lis,size)

# 每創造一次大頂堆排序,則選出首位為最大值,然後交換位置,繼續排序

for i in range(size)[::-1]:

lis[0] , lis[i] = lis[i], lis[0]

adjust_heap(lis,0,i)

print

"before the sort ..."

print lis_

print

"after the sort..."

print lis

輸出結果:

before the sort ...

[653

351801

993604

503360

964908

636]

after the sort...

[351, 360, 503, 604, 636, 653, 801, 908, 964, 993]

各種內排序演算法效能比較

各種內排序演算法效能比較 個人總結 穩定性最好情況 最壞情況 平均空間複雜度 確定最終位置 簡單選擇排序 屬於選擇排序 不穩定o n n 1趟 o n n 1趟 o n n 1趟 o 1 一趟排序後能確定某個元素的最終位置 直接插入排序 穩定o n n 1趟 o n n 1趟 反向有序 o n n ...

hash演算法及效能比較

拉鍊法就是通過陣列和鍊錶共同組成key和許多value的集合來減少衝突。鍊錶的缺點有兩個 第一,其長度太長時,會導致搜尋效能不好。第二,鍊錶在記憶體中的存放位址是不連續的,乙個快取行的大小是64b,而每乙個node可能佔16個位元組,如果是陣列,每次就可以連續的訪問4個node,但是對於鍊錶中的每乙...

各種排序演算法的時間效能比較

include include using namespace std 氣泡排序 原理 1 比較相鄰的前後二個資料,如果前面資料大於後面的資料,就將二個資料交換。2 這樣對陣列的第0個資料到n 1個資料進行一次遍歷後,最大的乙個資料就 沉 到陣列第n 1個位置。3 n n 1,如果n不為0就重複前面...