(快速排序的棧深度)7.1節中的quicksort演算法包含了兩個對其自身的遞迴呼叫。在呼叫partition後,quicksort分別遞迴呼叫了左邊的子陣列和右邊的子陣列。quicksort中的第二個遞迴呼叫並不是必須的。我們可以用乙個迴圈控制結構來代替它。這一技術稱為尾遞迴,好的編譯器都提供這一功能。考慮下面這個版本的快速排序,它摸擬了尾遞迴的情況:
a.證明:tai
l−re
curs
ive−
quic
ksor
t(a,
1,a.
leng
th)(a, 1, a.length)
tail−r
ecur
sive
−qui
ckso
rt(a
,1,a
.len
gth)
能正確地對陣列a
aa進行排序。
編譯器通常使用棧來儲存遞迴執行過程中的相關資訊,包括每一次遞迴呼叫的引數等。最新呼叫的資訊存在棧的頂部,而第一次呼叫的資訊存在棧的底部。當乙個過程被呼叫時,其相關資訊被壓入棧中;當它結束時,其資訊則被彈出。因為我們假設陣列引數是用指標來指示的,所以每次過程呼叫只需要o(1
)o(1)
o(1)
的棧空間。棧深度是在一次計算中會用到的棧空間的最大值。
b.請描述一種場景,使得針對乙個包含n
nn個元素陣列的tail-recursive-quicksort的棧深度是θ(n
)θ(n)
θ(n)
。c.修改tail-recursive-quicksort的**,使其最壞情況下棧深度是θ(l
gn)θ(lgn)
θ(lgn)
,並且能夠保持o(n
lgn)
o(nn)
o(nlgn
)的期望時間複雜度。
解
a.
tail-recursive-quicksort所做的事情與quicksort完全一樣。
在q ui
ckso
rt(a
,p,r
)(a, p, r)
quicks
ort(
a,p,
r)函式中,在遞迴呼叫qui
ckso
rt(a
,p,q
−1)(a, p, q-1)
quicks
ort(
a,p,
q−1)
後,緊接著遞迴呼叫qui
ckso
rt(a
,q+1
,r)(a, q+1, r)
quicks
ort(
a,q+
1,r)
。即在確定劃分子陣列後,選遞迴排序左邊的子陣列,再遞迴排序右邊的子陣列。
而在t ai
l−re
curs
ive−
quic
ksor
t(a,
p,r)
(a, p, r)
tail−r
ecur
sive
−qui
ckso
rt(a
,p,r
)函式中,在遞迴呼叫tai
l−re
curs
ive−
quic
ksor
t(a,
p,q−
1)(a, p, q-1)
tail−r
ecur
sive
−qui
ckso
rt(a
,p,q
−1),即排序左邊的子陣列之後,緊接著讓p=q
+1p = q+1
p=q+
1,再進入下一輪迭代。在下一輪迭代中,再排序右邊的子陣列。
b.
每次遞迴呼叫tail-recursive-quicksort都是針對左邊的子陣列。如果乙個陣列已經按單調遞增順序排好序,對該陣列呼叫partition後,所得到的2
22個子陣列中,左邊的子陣列規模為n−1
n-1n−
1,右邊的子陣列規模為0
00。左邊規模為n−1
n-1n−
1的子陣列通過遞迴呼叫tail-recursive-quicksort來排序。因此,可以得到規模為n的陣列的遞迴棧深度為d(n
)=d(
n−1)
+1d(n) = d(n-1) + 1
d(n)=d
(n−1
)+1,這個遞迴式的解為θ(n
)θ(n)
θ(n)
。c.
可以考慮這樣改進:每次遞迴呼叫tail-recursive-quicksort都排序規模較小的子陣列。
這個演算法的最壞情況發生在每次呼叫partition都產生乙個均衡的劃分。這種情況下,棧的深度可以表示為d(n
)=d(
n/2)
+1d(n) = d(n/2) + 1
d(n)=d
(n/2
)+1,其解為θ(l
gn)θ(n)
θ(lgn)
。由於這個演算法實質上與quicksort一致,所以它的期望時間複雜度依然為θ(n
lgn)
θ(nn)
θ(nlgn
)
演算法導論 思考題 4 3
a.利用主方法可得,t n n的log3 4次方 b.n f n lgn,不能應用主方法 共log3 n 1層,每層代價n lg n 3 的i次方 最後一層共n個 1 的結點,代價為 n t n n lg n 3 的i次方 n n lgn n n log3 2 n o n 又因為t n 最後一層代價...
演算法導論 思考題 8 4
寫一下我的思路,大概是對的,詳細證明不出來。設藍色水壺為a,紅色為b 先取乙個a1,對所有的b做一次比較,可以將b分為兩個部分,一部分大於a1,一部分小於a1 再取乙個a2,將b分為三個部分 再取a3,將b分為四個部分 假設現在b被分成了k個部分,b1,b2,b3.bk,每次取ai,都從b集合的一半...
演算法導論 思考題 4 5
這題實在沒什麼思路,網上找了一下答案。如果一開始就能夠確定好的晶元多於壞的,則可以保證每輪檢測結束好的晶元都多於壞的,一直到最後如果剩2塊晶元,則兩塊肯定都是好的 剩3塊晶元就再檢測一次,如果結果都是好的,就隨意取一片必定是好的 如果結果都是壞的,則剩下的那塊肯定是好的。來證明一下上面的結論 設有x...