关于您的评论“BST 中的节点有右子节点作为下一个最高节点”(假设这里“下一个最高”表示下一个顺序值) - 不,它没有。
如果右孩子没有左子树,可能就是这种情况,但并非总是如此。
下一个顺序值(我使用该术语而不是“最高”,因为后者可能与树高混淆,而“最大”意味着 特定(从低到高)顺序而不是 any order) 值来自两个地方之一。
首先,如果当前节点有一个右孩子,移动到那个右孩子然后,只要你能看到一个左孩子,就移动到它。
换句话说,以S 和D 作为源(当前)和目标(第二大):
S
/ \
x x <- This is the node your explanation chose,
/ \ but it's the wrong one in this case.
x x
/
D <----- This is the actual node you want.
\
x
否则(即如果当前节点有没有右孩子),你需要不断向上移动到父节点(所以节点需要一个右、左和父指针)直到你移动的节点from 是一个左孩子。如果您到达根节点并且仍然没有从左孩子向上移动,那么您的原始节点已经是树中的最高节点。
以图形方式说明整个过程:
x
\
D <- Walking up the tree until you came up
/ \ from a left node.
x x
\
x
/ \
x S
/
x
此类函数的伪代码(涵盖这两种情况)将是:
def getNextNode (node):
# Case 1: right once then left many.
if node.right != NULL:
node = node.right
while node.left != NULL:
node = node.left
return node
# Case 2: up until we come from left.
while node.parent != NULL:
if node.parent.left == node:
return node.parent
node = node.parent
# Case 3: we never came from left, no next node.
return NULL
由于努力与树的高度成正比(我们要么向下,要么向上然后向下),一个平衡树的时间复杂度为O(log N),因为高度有一个logN 与项目数的关系。
这本书在这里讨论的是平衡树,因为它包含了关于它们的如下 sn-ps:
- 此查找是一种快速操作,因为您在每次迭代中从搜索中消除了一半的节点。
- 查找是二叉搜索树中的
O(log(n)) 操作。
- 如果您能保证每次迭代中剩余待搜索的节点数减半或接近减半,则仅查找
O(log(n))。
因此,虽然它在最后的引用中承认 BST 可能不是平衡的,但O(log N) 属性仅适用于那些是的变体。
对于非平衡树,复杂度(最坏情况)为O(n),因为您最终可能会得到如下退化树:
S D
\ /
x x
\ \
x x
\ \
x x
\ \
x x
/ \
D S