演算法導論12 2

2022-07-07 15:30:15 字數 3240 閱讀 5366

本小節介紹了二叉搜尋樹的查詢操作,包括\(search, minimum,maximum, successor, predecessor\)這\(5\)個操作,這五個操作均可以在\(o(h)\),\(h\)是當前二叉樹的高度。

遞迴實現:

tree-search(x, k)

if x == nil or k == x.key

return x

if k < x.key

return tree-search(x.left, k)

else

return tree-search(x.right, k)

迭代實現:

iterative-tree-search(x, k)

while x != nil and key != x.key

if k < x.key

x = x.left

else

x = x.right

return x

獲取最小值:

tree-minimum(x)

while x.left != nil

x = x.left

return x

最左子節點就是最小值。

獲取最大值:

tree-maximum(x)

while x.right != nil

x = x.right

return x

最右子節點就是最大值。

後繼節點:

tree-successor(x)

if x.right != nil

return tree-minimum(x.right)

y = x.p

while y != nil and x == y.right

x = y

y. = y.p

return y

上述演算法為中序遍歷存在;

乙個節點的後繼節點有兩種情況:

當前節點\(x\)存在右子樹,則後繼節點就是右子樹中的最小值。

當前節點不存在右子樹,則後繼節點為某個祖先節點,此祖先節點的左子樹包含當前節點。

前驅節點:

乙個節點的前驅節點有兩種情況:

當前節點存在左子樹,則前驅節點就是左子樹中的最大值。

當前節點不存在左子樹,則前驅節點為某個祖先節點,此祖先節點的右子樹包含當前節點。

寫出\(tree-minimum\)和\(tree-maximum\)的遞迴版本。

tree-minimum(x)

if x.left == nil

return x

tree-minimum(x.left)

tree-maximum(x)

if x.right == nil

return x

tree-maximum(x.right)

寫出過程\(tree-predecessor\)的偽**。

tree-predecesssor(x)

if x.left != nil

return tree-maximum(x.left)

y = x.p

while y != nil and x == y.left

x = y

y = y.p

return y

\(bunyan\)教授認為他發現了要給二叉搜尋樹的重要性質。假設在一顆二叉搜尋樹中查詢乙個關鍵字\(k\),查詢結束於乙個樹葉。考慮三個集合:\(a\)為查詢路徑左邊的關鍵字集合;\(b\)為查詢路徑上的關鍵字集合;\(c\)為查詢路徑右邊的關鍵字集合。\(bunyan\)教授聲稱:任何\(a\in a, b \in b, c\in c\),一定滿足\(a\le b\le c\)。請給出該教授這個論斷的乙個最小可能的反例。

查詢節點20,則集合a=, 集合b=,集合c=,並不滿足集合a中的任意元素<=b中的。

證明:如果一顆二叉搜尋樹中的乙個節點有兩個孩子,那麼它的後繼沒有左孩子,它的前驅沒有右孩子。

如果當前節點的後繼有左孩子,那就代表有乙個節點比該後繼節點小,但是實際上這個節點應該是當前節點,這就導致了二叉搜尋樹的錯誤。前驅節點沒有右孩子也是一樣。

考慮一顆二叉搜尋樹\(t\),其關鍵字互不相同。證明:如果\(t\)中乙個節點\(x\)的右子樹為空,且\(x\)有乙個後繼\(y\),那麼\(y\)一定是\(x\)的最底層祖先,並且其左孩子也是\(x\)的祖先。(注意:每個節點都是它自己的祖先。)

前驅節點:

乙個節點的前驅節點有兩種情況:

當前節點存在左子樹,則前驅節點就是左子樹中的最大值。

當前節點不存在左子樹,則前驅節點為某個祖先節點,此祖先節點的右子樹包含當前節點。

對於一顆有\(n\)個節點的二叉搜尋樹,有另一種方法來實現中序遍歷,先呼叫\(tree-minimum\)找到這棵樹中的最小元素,然後再呼叫\(n-1\)次的\(tree-successor\)。證明:該演算法的執行時間為\(\theta(n)\)。

對\(n\)個元素進行遍歷,無論整出什麼么蛾子,時間複雜度都在\(\theta(n)\)。

證明: 在一棵高度為\(h\)的二叉搜尋樹中,不論從哪個節點開始,\(k\)次連續的\(tree-successor\)呼叫所需時間為\(o(k+h)\)。

複雜度裡有乙個\(k\)是因為呼叫了\(k\)次,有乙個\(h\)是因為需要向上找到祖先節點;

設\(t\)是一顆二叉搜尋樹,其關鍵字互不相同;設\(x\)是乙個葉節點,\(y\)為其父節點。證明:\(y.key\)或者是\(t\)樹中大於\(x.key\)的最小關鍵字,或者是\(t\)樹中小於\(x.key\)的最大關鍵字。

顯然如此。

演算法導論12 2節習題解答

clrs 12.2 1 c錯,240及240之後的節點應該都為911左子樹上的節點,那麼所有節點必然小於或等於911,但點912明顯違反了。clrs 12.2 2 search minimum x if left x nil search minimum left x return x search...

演算法導論12 2查詢二叉搜尋樹 練習總結

12.2 1 假設一棵二叉搜尋樹中的結點在 1 到 1000 之間,現在想要查詢數值為 363 的結點。下面序列中哪個不是查詢過的序列?a.2,252,401,398,330,344,397,363。b.924,220,911,244,898,258,362,363。c.925,202,911,24...

演算法導論 隨機演算法

一.概率分布 對於有些問題本身是屬於概率問題,如僱傭問題 對於此類問題,我們需要利用概率分析來得到演算法的執行時間,有時也用來分析其他的量。例如,僱傭問題中的費用問題也需要結合概率分析來計算得到。為了使用概率分析,我們必須使用或者假設已知關於輸入的概率分布,然後通過分析該演算法計算出平均情況下的執行...