性质
设 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