歸併排序運用分治演算法與遞迴思想,那麼其雙遞迴究竟是怎樣的呢?今天被困擾了一會一直覺得並沒有完全理解,後通過思考以及查閱資料,弄懂了其遞迴的真正實現過程!
寫給已了解歸併排序的coder
code:
void
merge
(int r,
int r1,
int s,
int m,
int t)
//歸併子串行
while
(i<=m) r1[k++
]=r[i++];
while
(j<=t) r1[k++
]=r[j++];
}void
mergesort
(int r,
int s,
int t)
}
首先一定要明白在遞迴中每乙個條語句是具有相同的執行順序的。也就是說每次在mergesort函式中我所標的1 2 3 4是具有相同的執行順序的~
上圖說明 為節約時間 直接插圖了
假設s=1 t=8
看好上方**的1 2 3 4條語句標註
一.就是說到最後s=1 t=2的時候(此時相當於"二位置"在執行1語句),此時mergesort會執行完1語句(此時呼叫函式時s=1 t=1會執行return語句),之後執行2語句(此時呼叫函式是s=1 t=1會執行return語句),再然後依次執行3語句,4語句。
二.這樣執行完過後標註的"二位置"才會去執行2語句,執行完2語句之後"三位置右邊藍色部分"會產生和一步驟相同的操作!
三.那麼"二位置"是不是就相當於最上層函式執行完1語句呢?
我的理解就是這樣 感覺對於複雜遞迴 從根去理解好還是需要好好去思考的
例題小和問題
昨天無意看到了一道關於歸併排序的應用題 這道題如果知道應用歸併排序實現就不是那麼難了
[1,3,4,2,5]
1左邊比1小的數:沒有
3左邊比3小的數:1
4左邊比4小的數:1,3
2左邊比2小的數:1
5左邊比5小的數:1,3,4,2
所以小和為1+1+3+1+1+3+4+2=16
python實現
def
get_smallsum
(arr)
:if arr is
none
orlen
(arr)
<2:
return
0return sssum(arr,0,
len(arr)-1
)def
sssum
(arr, l, r)
:if l == r:
return
0 mid = l +
((r - l)//2
)return sssum(arr, l, mid)
+ sssum(arr, mid +
1, r)
+ merge(arr, l, mid, r)
# 求左半部分的小和 + 右半部分的小和 + 合併產生的小和
defmerge
(arr,l,mid,r)
: left = l
right = mid +
1 res =
sum=
0# 在歸併排序中求得小和
while left<=mid and right<=r:
# 只有右邊大於左邊才會貢獻小和
if arr[left]
< arr[right]
:sum
+= arr[left]
*(r-right+1)
) left+=
1else:)
right+=
1while left<=mid:
) l+=
1while right<=r:
) right+=
1 arr[l:r+1]
= res
return
sumif __name__ ==
"__main__"
: arr =[1
,3,4
,2,5,7
]print
(get_smallsum(arr)
)
歸併排序 分治演算法佇列遞迴實現
分治思想就是先分成一小塊一小塊,最後再一步步合併起來,最後完成排序 下面 需要注意的地方是 int asize arr.size 我一開始的時候直接在for迴圈中使用arr.size 但是我這個for迴圈中arr是在不斷pop的,所以導致其size也在不斷變化,不能達到對半分的效果,用乙個變數來把最...
遞迴與分治 歸併排序
描述 給定乙個數列,用歸併排序演算法把它排成公升序。輸入 第一行是乙個整數n n不大於10000 表示要排序的數的個數 下面一行是用空格隔開的n個整數。輸出 輸出排序後的數列,每個數字佔一行。輸入樣例 5 3 2 1 4 5 輸出樣例 1 2345 基本思路 歸併排序是將一組無序的數列,先一分為二,...
分治演算法 歸併排序
問題描述 輸入 待排序列r n 待排區間 s,t 輸出 公升序序列r s r t 分析 1 劃分 2 求解子問題 3 合併 歸併排序首先執行劃分過程,直到子串行長度為1,再在回溯的過程中排序。在merge 函式中,由於回溯回來的兩個子串行已經有序,所以只需依次取出兩者中最小值中的較小者即可。incl...