二叉搜尋樹(binary search tree)
阿新 • • 發佈:2018-12-16
性質
設 x 是二叉搜尋樹中的一個結點。如果 y 是 x 左子樹中的一個結點,那麼 y.key ≤ x.key。如果 y 是 x 右子樹中的一個結點,那麼 y.key ≥ x.key。
特性
期望高度:height = O(lgn)
基本操作平均時間複雜度:Operations = Θ(lgn)
操作
遍歷:時間複雜度 θ(n),n 為總結點數。
INORDER_TREE_WALK
if x != NIL
INORDER_TREE_WALK(x.left)
print x.key
INORDER_TREE_WALK(x .right)
搜尋指定鍵值:中序遍歷查詢指定鍵值。時間複雜度 O(height)。
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 k != x.key
if k < x.key
x = x.left
else
x = x.right
return x
查詢最小值:遞迴查詢最左結點。時間複雜度 O(height)。
TREE_MINIMUM(x)
while x.left != NIL
x = x.left
return x
查詢最大值:遞迴查詢最右結點。時間複雜度 O(height)。
TREE_MAXIMUM(x)
while x.right != NIL
x = x.right
return x
後繼:時間複雜度 O(height)。
實現分為兩種情況:
* 結點 x 的右子樹非空,則右子樹的最左結點就是 x 的後繼。
* 結點 x 的右子樹為空,則後繼 y 滿足: y 的左子樹存在且同時是 x 的祖先, y 是符合前面性質的最底層的 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
前驅:時間複雜度 O(height)。
實現分為兩種情況:
* 結點 x 的左子樹非空,則左子樹的最右結點就是 x 的前驅。
* 結點 x 的左子樹為空,則前驅 y 滿足:y 的右子樹存在且同時是 x 的祖先,y 是符合前面性質的最底層的 x 的祖先。
TREE_PREDECESSOR(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
插入:時間複雜度 O(height)。
實現:
1. 查詢新結點放置的位置。
* 從樹的根節點開始,新結點和當前結點的值比較,根據情況向左或右遍歷。
* 迴圈a,直到得出的當前節點為NILL為止,這個當前結點的位置就是新結點要插入的位置。
2. 放置新結點。根據新結點與前面得到的結點的父結點比較,確定位置並插入。
TREE_INSERT(T, z)
y = NIL
x = T.root
while x != NIL
y = x
if z.key < x.key
x = x.left
else
x = x.right
z.p = y
if y == NIL
T.root = z // tree T was empty
elseif z.key < y.key
y.left = z
else
y.right = z
刪除:時間複雜度 O(height)
實現策略分為三種情況,設要刪除的結點為 z :
* 如果 z 沒有孩子結點,那麼簡單地將它刪除,並修改它的父結點,用NIL作為孩子來替換 z 。
* 如果 z 有一個孩子,那麼將這個孩子提升到樹中 z 的位置上,並修改 z 的父結點,用 z 的孩子來替換 z 。
* 如果 z 有兩個孩子, 那麼找 z 的後繼 y (一定在 z 的右子樹上),並讓 y 佔據樹中 z 的位置。z 的原右子樹部分稱為y的新的右子樹,並且 z 的左子樹成為 y 的新的左子樹。
TRANSPLANT(T, u, v)
if u.p == NIL
T.root = u
elseif u == u.p.left
u.p.left = v
else
u.p.right = v
if v != NIL
v.p = u.p
TREE_DELETE(T, z)
if z.left == NIL
TRANSPLANT(T, z, z.right)
elseif z.right == NIL
TRANSPLANT(T, z, z.left)
else
y = TREE_MINIMUM(z.right)
if y.p != z
TRANSPLANT(T, y, y.right)
y.right = z.right
y.right.p = y
TRANSPLANT(T, z, y)
y.left = z.left
y.left.p = y