效能穩定
平均時間複雜度為 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就重複前面...