02歸併排序

2021-10-16 03:06:19 字數 4020 閱讀 9726

"""

基於分治的思想

1.選中陣列中間元素為分界點

2.遞迴排序分界點的左邊和右邊

3.歸併兩個有序的陣列,合二為一(難點)

歸併排序需要建立額外的陣列

"""def

merge_sort

(q, l, r)

:if l >= r:

return

mid =

(l + r)//2

# 這裡取陣列的中間元素作為分界點

merge_sort(q, l, mid)

# 歸併分界點左邊的元素

merge_sort(q, mid +

1, r)

# 歸併分界點右邊的元素

temp =

i = l

j = mid +

1while i <= mid and j <= r:

if q[i]

< q[j]:)

i +=

1else:)

j +=

1# 兩個陣列比較,可能會出現,乙個陣列的元素全部新增進temp陣列了,乙個沒有完全新增進去,將剩下的陣列中的元素全部新增進temp陣列

while i <= mid:

) i +=

1while j <= r:

) j +=

1# 將本次遞迴中temp陣列中的有序元素複製到原陣列相應的位置中

i = l # q的指標,從left開始

j =0# temp的指標,從0開始

while i <= r:

q[i]

= temp[j]

i +=

1 j +=

1def

main()

: n =

int(

input()

)# 輸入陣列長度

q =[int

(x)for x in

input()

.split()]

# 用生成式,將第二行的輸入轉成陣列,以空格為分隔符

merge_sort(q,

0, n -1)

for elem in q:

print

(elem, end=

' ')

if __name__ ==

'__main__'

: main(

)

"""

基於分治的思想

1.選中陣列中間元素為分界點

2.遞迴排序分界點的左邊和右邊

3.歸併兩個有序的陣列,合二為一(難點)

歸併排序需要建立額外的陣列

"""def

merge_sort

(q, l, r)

:if l >= r:

return

mid =

(l + r)//2

# 這裡取陣列的中間元素作為分界點

merge_sort(q, l, mid)

# 歸併分界點左邊的元素

merge_sort(q, mid +

1, r)

# 歸併分界點右邊的元素

i = l

j = mid +

1 cur =

0while i <= mid and j <= r:

if q[i]

< q[j]

: temp[cur]

= q[i]

i +=

1 cur +=

1else

: temp[cur]

= q[j]

j +=

1 cur +=

1# 兩個陣列比較,可能會出現,乙個陣列的元素全部新增進temp陣列了,乙個沒有完全新增進去,將剩下的陣列中的元素全部新增進temp陣列

while i <= mid:

temp[cur]

= q[i]

i +=

1 cur +=

1while j <= r:

temp[cur]

= q[j]

j +=

1 cur +=

1 i, j = l,

0while i <= r:

q[i]

= temp[j]

j +=

1 i +=

1if __name__ ==

'__main__'

: n =

int(

input()

)# 輸入陣列長度

temp =[0

]* n

q =[int

(x)for x in

input()

.split()]

# 用生成式,將第二行的輸入轉成陣列,以空格為分隔符

merge_sort(q,

0, n -1)

for elem in q:

print

(elem, end=

' ')

2021/1/20:

下面這種寫法省去了最後將ans陣列複製到原陣列中的步驟,直接將他返回就好了。區別就是,他在merge_sort的過程中,是將原陣列切片成許多個小陣列,然後用歸併的思想,每兩個,從前往後進行。至於和前面的區別(就是為啥可以直接返回),暫時還沒想透。先放這,等想透了在補上。

(已補,我覺得是對的

吧 心虛~~~)

# 2021/1/23更新

defmerge_sort

(q):

length =

len(q)

if length <=1:

return q

mid =

(length -1)

>>

1 ql = merge_sort(q[

:mid +1]

)# ql指左邊已經排序好的部分

qr = merge_sort(q[mid +1:

])# qr指右邊已經排序好的部分

# 定義乙個空列表存放待會比較後的資料 因為遞迴到最後 就是將原陣列分成兩部分進行比較 前面一部分排序好的 後面一部分排序好的

# 所以最後ans列表中最後存放的就是最終的資料 可以直接返回

ans =

i = j =

0while i <

len(ql)

and j <

len(qr)

:if ql[i]

<= qr[j]:)

i +=

1else:)

j +=

1if i <

len(ql)

: ans.extend(ql[i:])

if j <

len(qr)

: ans.extend(qr[j:])

return ans

if __name__ ==

'__main__'

: n =

int(

input()

) q =

list

(map

(int

,input()

.split())

)print

(' '

.join(

map(

str, merge_sort(q)))

)

2021/1/23:

今天重寫了一下歸併,發現不理解的基礎上強記的確不好受,在腦子裡微薄的「理解」基礎上寫了一遍後,報錯,用**對比工具一行行的對著,發現忽略了幾個小點,導致我寫的歸併是個錯誤弟弟。具體如下:

tip:暫時腦子裡就這麼多,以後有想到的糾錯的會繼續更。菜菜默淚,上圖。

演算法筆記 歸併排序02

步驟為 歸併排序是採用分治法的乙個非常典型的應用。歸併排序的思想就是先遞迴分解陣列,再合併陣列。將陣列分解最小之後,然後合併兩個有序陣列,基本思路是比較兩個陣列的最前面的數,誰小就先取誰,取了後相應的指標就往後移一位。然後再比較,直至乙個陣列為空,最後把另乙個陣列的剩餘部分複製過來即可。usr bi...

歸併排序(2 路歸併排序)

遞迴寫法 include define maxn 100 void merge int a,int l1,int r1,int l2,int r2 將陣列a的區間 l1,r1 和區間 l2,r2 合併為乙個有序區間 else while i r1 while j r2 for int i 0 i非遞...

python歸併排序 python 歸併排序

排序思路 1.將陣列分成兩組a,b,建立臨時陣列 c,c長度 a b 2.i,j分別屬於a,b 3.若a i b j 將b j 放入c,j 否則 a i 放入c,i 4.迴圈3步驟,將a或b中剩餘的元素放入c,再將c複製到陣列中 5.遞迴3 4直到a,b序列的長度 1 歸併排序 class merg...