【问题标题】:Finding the parent of a node in a Binary tree在二叉树中查找节点的父节点
【发布时间】:2014-05-25 14:59:29
【问题描述】:

我正在尝试编写一种方法来查找给定节点的父节点。这是我的方法。
我创建了一个 BinaryNode 对象 r,它最初是指 root。

    public BinaryNode r=root;
    public BinaryNode parent(BinaryNode p){
    BinaryNode findParent=p;        
        if (isRoot(findParent) || r==null){
                return null;
        }
        else{
            if(r.left==findParent || r.right==findParent)
                return r;
            else{
                if (r.element<findParent.element)
                    return parent(r.right);
                else
                    return parent(r.left);
            }
        }
    }  

这段代码不能正常工作。我认为那是因为 r 是一个空对象。因为当我这样做时

if (isRoot(findParent) || r==null){
                System.out.println(r==null);
                return null;}  

r==null 计算结果为true。为什么会发生这种情况,因为我已将节点插入为

public static void main (String args[]){
        BinaryTree t=new BinaryTree();
        t.insert(5);
        t.insert(t.root,4);
        t.insert(t.root,6);
        t.insert(t.root,60);
        t.insert(t.root,25);
        t.insert(t.root,10);  

并且根不为空。
有人可以指出为什么会发生这种情况,以及我为了找到父节点而尝试做的事情是否在逻辑上是正确的。

【问题讨论】:

  • 如何调用 find parent 方法?你提供了哪些论据?
  • @wastl: findParent 不是一个方法,它是一个 binaryNode 存储我们需要找到的父节点的节点
  • 对不起,我的意思是 parent(BinaryNode) 方法
  • @wastl:如果我想找到位于root左边的节点的父节点,该方法可以称为`parent(root.left)`
  • 您是否检查过 isRoot(findParent) 的计算结果是否为 true?

标签: java data-structures binary-tree parent


【解决方案1】:

问题是您必须跟踪当前节点,同时保留要查找的父节点。据我了解您的代码,您保留变量,但永远不要更改它
我建议使用辅助功能。这看起来像这样:

public BinaryNode parent(BinaryNode p){
    parentHelper(root,p)
}
private BinaryNode parentHelper(BinaryNode currentRoot, BinaryNode p) {        
    if (isRoot(p) || currentRoot==null){
            return null;
    }
    else{
        if(currentRoot.left==p || currentRoot.right==p)
            return currentRoot;
        else {
            if (currentRoot.element<p.element) {
                return parentHelper(currentRoot.right,p);
            }
            else {
                return parentHelper(currentRoot.left,p);
            }
        }
    }
}  

【讨论】:

  • 感谢您提供的答案。我意识到我从未更改当前变量并找到了一种我认为可以解决此问题的方法。一开始我试图将根节点获取到变量 r .为此我在 parent() 方法之外有public BinaryNode r=root;。然后检查我做了public BinaryNode parent(BinaryNode p){ System.out.println("r"+r.element); 在那里我得到一个空指针异常
  • 这意味着 r 是一个空对象,这就是为什么 if (isRoot(findParent) || r==null){ 总是被评估并且在那里它返回 false 并且其余的代码甚至没有运行。**为什么 r 变成一个空对象* *.这是我的二叉树实现。 public class BinaryTree { private BinaryNode root; public BinaryTree(){ root= null;}BinaryTree(int nodeValue){ root=new BinaryNode(nodeValue);} 我将元素插入到它作为t.insert(5); t.insert(t.root,4);
  • 您的代码运行我认为return parent(currentRoot.right,p); 应该更改为return parentHelper(currentRoot.right,p);
【解决方案2】:

我将值与值进行比较,因为我没有定义比较节点的方式。

    public static Node FindParent(Node root, Node node)
    {
        if (root == null || node == null)
        {
            return null;
        }
        else if ( (root.Right != null && root.Right.Value == node.Value) || (root.Left != null && root.Left.Value == node.Value))
        {
            return root;
        }
        else
        {
            Node found = FindParent(root.Right, node);
            if (found == null)
            {
                found = FindParent(root.Left, node);
            }
            return found;
        }
    }

【讨论】:

    【解决方案3】:

    使用两个参数:一个用于当前节点,一个用于正在搜索的节点。

    【讨论】:

    • 虽然这是正确的,但这并不能解释 什么 OP 的代码有问题以及 为什么 OP 应该这样做。毫无疑问,添加这些将是一个更好的答案。
    • 嗯,这个问题看起来像是一个家庭作业,所以我不想给出太多提示;)
    • 然后将此作为评论发布。我认为这对于答案来说太短(无论是从长度还是从问题上)。
    • @peq :我认为 r 充当了一个变量来保持当前节点的关心
    • @peq:这不是家庭作业。我正在学习数据结构,在此基础上我正在做树。我刚刚尝试写一个方法来找到父母只是为了帮助自己学习它
    【解决方案4】:

    这是使用堆栈数据结构查找父节点的代码。

    Stack<TreeNode> parentStack = new Stack<TreeNode>();
    
    public static void inOrderTraversal(TreeNode root){
                if(root != null){
                    if(parentStack.size()==0){
                        parentStack.push(root);
                    }
                    if(root.getLeftChild()!=null){
                        parentStack.push(root); 
                        inOrderTraversal(root.getLeftChild());  
                    }
                    parent = parentStack.pop();
                    System.out.println(root.getNodeValue()+"'s parent is "+parent.getNodeValue());
                    if(root.getRightChild()!=null){
                        parentStack.push(root);
                        inOrderTraversal(root.getRightChild());
                    }
                }
                else{
                    if(root==null){System.err.println("Can't process a empty root tree");}
                }
            }
    

    【讨论】:

      【解决方案5】:

      我更愿意将尽可能多的工作委托给较低级别​​的组件,在本例中是 Node 类。回复:找到一个节点的父节点,我就是这样做的......

      template <typename T>
      Node<T>* Node<T>::parent (const Node<T>* node) 
      {
          if (node)
          {
              if (*node < *this)
              {
                  if (left && (*node < *left))
                      return left->parent (node);
                  return this;
              }
              if (*node > *this)
              {
                  if (right && (*right > *node))
                      return right->parent (node);
                  return this;
              }
          }
          return nullptr;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-07
        • 2015-08-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多