BST,找到下一个最高节点

时间:2014-01-08 08:50:57

标签: data-structures tree

在BST中,根据“已曝光的编程访谈”

“给定一个节点,您甚至可以在O(log(n))时间内找到下一个最高节点”Pg 65

BST中的节点将右子节点作为下一个最高节点,那么为什么O(log(n))?请更正

首先回答这个问题,然后否定它

3 个答案:

答案 0 :(得分:13)

“BST中的节点将右子节点作为下一个最高节点”(假设此处“下一个最高”表示下一个最大值) - 否,它不会。 可以,如果它没有左边节点,但并非总是如此(见下面的第1点)。

下一个最大的值(使用该术语而非“最高”,因为后者可能与树高混淆)值来自两个地方之一:

首先,如果当前节点有一个正确的孩子,移动到那个正确的孩子那么,只要你能看到一个左孩子,就移动到它。

换句话说(S和D是源和目的地):

   S
  / \
 x   x <- This is the node your simple explanation chose,
    / \    but it's the wrong one in this case.
   x   x
  / \
 D   x
  \
   x

否则(当前节点有 no 右子)你需要连续向上移动到父节点(所以节点需要右,左和父指针),直到你移动的节点 是一个左撇子。如果你到达root并且仍然没有从左子项向上移动,那么原始节点已经是树中最高的。图形上可能是:

x
 \
  D
 / \
x   x
 \
  x
 / \
x   S
   /
  x

这种功能的伪代码是:

def getNextNode (node):
    if node.right != NULL:
        node = node.right
        while node.left != NULL:
            node = node.left
        return node

    while node.parent != NULL:
        if node.parent.left == node:
            return node.parent
        node = node.parent

    return NULL

由于努力量与树的高度成正比,因此平衡树(例如红黑,2-3-4和AVL)的时间复杂度为O(log N) )因为高度与项目数有logN关系。这本书正在谈论平衡树,因为它包含了关于它们的片段:

  • 此查找是一种快速操作,因为您在每次迭代时从搜索中消除了一半节点。
  • 查找是二叉搜索树中的O(log(n))操作。
  • 查找只有O(log(n)),如果您可以保证每次迭代时剩余要搜索的节点数量减半或几乎减半。

所以,虽然它在最后一句话中承认BST可能是平衡的,但O(log N)属性仅适用于那些的变体。 < / p>

对于非平衡树,复杂性(最坏情况)将是O(n),因为你最终会得到退化树,如:

S             D
 \           /
  x         x
   \         \
    x         x
     \         \
      x         x
       \         \
        x         x
       /           \
      D             S

答案 1 :(得分:1)

这是我在Java中的伪实现。希望它有所帮助。

节点结构

public Class Node{

int value {get, set};
Node leftChild {get,set};
Node rightChild{get, set};
Node parent{get,set};
}

查找下一个最高节点的功能

public Node findNextBiggest(Node n){
    Node temp=n;
    if(n.getRightChild()==null)
    {
        while(n.getParent()!=null && temp.getValue()>n.getParent().getValue())
        {
            n=n.getParent():
        }
        return n.getParent();
    }
    else
    {
        n=n.getRightChild();
        while (n.getLeftChild()!=null && n.getLeftChild().getValue()>temp.getValue())
        {
            n=n.getLeftChild();
        }
    return n;
    }
}

答案 2 :(得分:1)

我认为,通过简单地找到节点的Inorder Successor,我们可以找到下一个最高节点。

步骤 -

  • 首先,转到节点的右边孩子。
  • 然后尽可能向左移动。到达叶节点时,打印该叶节点,因为该节点是与给定节点相比的下一个最高节点。