歸併排序和逆序列演算法

2021-10-06 09:52:51 字數 3108 閱讀 3745

說明排序問題是資料處理中常會遇到的問題,通常是解決相關問題的前處理過程。這類演算法目前有很多,比如相對暴力的氣泡排序和插入排序法。這類暴力求解演算法的時間複雜度一般為o(n2),顯然這個時間複雜度無法滿足工程的應用。所以,在暴力求解的基礎上發展出了歸併排序、堆排序以及快速排序,這類排序演算法時間複雜度為o(nlog2n)。上述演算法都是基於比較法去實現排序,還有部分演算法並未採用比較法,這部分演算法排序速度要更快一些,這類演算法會在後面介紹。

本部落格中展示了插入排序、歸併排序以及基於歸併排序演算法衍生出的查詢逆序列演算法**。

def

insersort

(my_list)

:for i in

range(1

,len

(my_list)):

key=my_list[i]

j=i-

1while j>=

0and key: my_list[j+1]

=my_list[j]

j-=1 my_list[j+1]

=key

def

merge

(leftlist,rightlist)

: tmplist=

i=0 j=

0while i<

len(leftlist)

and j<

len(rightlist)

:if leftlist[i]

<=rightlist[j]:)

i+=1else:)

j+=1if j==

len(rightlist)

:for k in leftlist[i:]:

else

:for k in rightlist[j:]:

return tmplist

defmergesort

(my_list):if

len(my_list)

<=1:

return my_list

middle=

int(

len(my_list)/2

) left=mergesort(my_list[

:middle]

) right=mergesort(my_list[middle:])

return merge(left,right)

if __name__==

'__main__'

: testlist=[5

,8,24

,1,44

,0]print

(mergesort(testlist)

)

def

getpair

(left,right,pairlist)

:

tmplist=

#返回排序好的列表

i=j=

0while i<

len(left)

and j<

len(right)

:if left[i]

<=right[j]:)

i+=1else:)

for z in left[i:]:

) j+=

1if i==

len(left)

:for k in right[j:]:

else

:for k in left[i:]:

return tmplist

defreverseorderpair

(my_list,mypair):if

len(my_list)

<=1:

return my_list

mid=

int(

len(my_list)/2

) leftlist=reverseorderpair(my_list[

:mid]

,mypair)

rightlist=reverseorderpair(my_list[mid:

],mypair)

return getpair(leftlist,rightlist,mypair)

if __name__==

'__main__'

: pair=

testlist=[1

,2,3

,4,5

,6,7

,0,12

,2,4

,7,66

,45,85

,14,2

,5,8

,6,5

,12,44

,3,5

]print

(reverseorderpair(testlist,pair)

)print

(pair)

print

(len

(pair)/2

)

插入排序比較簡單,只有兩次迴圈巢狀,可以看出一共遍歷了n-1 + n-2 + … + 2 + 1 = n * (n-1) / 2 = 0.5 * n ^ 2 - 0.5 * n,所以時間複雜度是o(n2)。

歸併演算法主要是考慮兩個函式的時間花銷:一、陣列劃分函式mergesort();二、有序陣列歸併函式merge()。

merge()函式的時間複雜度為o(n),因為該函式**中有2個長度為n的迴圈。

mergesort()在計算長度為n的歸併排序所消耗的時間 t[n],那麼呼叫mergesort()函式劃分兩部分,那每一小部分排序好所花時間則為 t[n/2],而最後把這兩部分有序的陣列合併成乙個有序的陣列merge()函式所花的時間為 o(n),最後時間複雜度的計算公式為:

t [n

]=2t

[n/2

]+o(

n)

t[n] = 2t[n/2] + o(n)

t[n]=2

t[n/

2]+o

(n)這種遞迴呼叫函式時間複雜度的計算可以使用主方法或者列舉法。歸併演算法的整個過程展開來就是乙個具有n個根節點的二叉樹結構,共有log2n個層,每一層都需要進行時間複雜度為 o(n)的merge()函式,所以歸併演算法時間複雜度為o(nlog2n)。

歸併演算法 歸併排序

歸併演算法 歸併排序 這周需要用到歸併演算法,於是找了找相關的資料,整理如下 歸併排序 merge sort 是利用 歸併 技術來進行排序。歸併是指將若干個已排序的子檔案合併成乙個有序的檔案。兩路歸併演算法 1 演算法基本思路 設兩個有序的子檔案 相當於輸入堆 放在同一向量中相鄰的位置上 r low...

最大子串行和 歸併排序

今天看劉汝佳看到歸併排序還看了分治求最大子串行和,感覺簡單多了,剛開始學時看了幾天都沒看會,現在在看感覺果然不一樣 先打乙個歸併排序,馬上就打子串行和,哎 為什麼總打這些水題呢,一是我現在很水,二是涉及人生完不完整的八數碼暫時理解不深 哈哈 勉強看懂,等過幾天就會相對高階的演算法了,這裡複製上一段話...

歸併排序演算法

include stdafx.h include include include 合併兩段已經排好序的列表 void merge int list int mergelist int left int mid int right else if i mid else 將列表list按照seglen分...