本小節介紹了二叉搜尋樹的查詢操作,包括\(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...
演算法導論 隨機演算法
一.概率分布 對於有些問題本身是屬於概率問題,如僱傭問題 對於此類問題,我們需要利用概率分析來得到演算法的執行時間,有時也用來分析其他的量。例如,僱傭問題中的費用問題也需要結合概率分析來計算得到。為了使用概率分析,我們必須使用或者假設已知關於輸入的概率分布,然後通過分析該演算法計算出平均情況下的執行...