在二叉搜索树中找到一个节点的父节点

Posted

技术标签:

【中文标题】在二叉搜索树中找到一个节点的父节点【英文标题】:Find the parent node of a node in binary search tree 【发布时间】:2015-08-24 12:55:51 【问题描述】:

所以我想在二叉树中找到一个节点的父节点。 假设我通过一个文本文件在树中输入了 30,15,17,45,69,80,7。

树应该是

                 30
             15       45
          7      17       69
                               80

这是我的代码:

Node*  BST::searchforparentnode(Node* pRoot, int value)

   if(pRoot->pleft == NULL && pRoot->pright == NULL)
    return NULL;

   if(pRoot->pleft->value == value || pRoot->pright->value == value)
    return pRoot;

   if(pRoot->value > value)
    return searchforparentnode(pRoot->pleft,value);

   if(pRoot->value < value)
    return searchforparentnode(pRoot->pright,value);

在这种情况下,我不考虑用户是否输入根节点的值。

问题是,当我输入 15,17,7 时,根节点左分支中的所有值都出来了。但是当我想从右分支(69,80)中找到值的父节点时,除了 45,程序停止运行。

您知道是什么导致了这个错误吗?感谢阅读。

【问题讨论】:

您确定您的树结构良好吗?使用调试器来挖掘问题。 【参考方案1】:

看来45 没有left 节点,它是NULL,所以检查pRoot-&gt;pleft-&gt;value == value 是未定义的行为。

             30
            /  \
         15     45
        /   \     \
      7      17    69
                     \
                      80

所以你需要做一个检查,比如:

Node*  BST::searchforparentnode(Node* pRoot, int value)

    if(pRoot->pleft == NULL && pRoot->pright == NULL)
       return NULL;

    if( (pRoot->pleft != NULL && pRoot->pleft->value == value)
        || (pRoot->pright != NULL && pRoot->pright->value == value))
       return pRoot;

    if(pRoot->value > value)
       return searchforparentnode(pRoot->pleft,value);

    if(pRoot->value < value)
       return searchforparentnode(pRoot->pright,value);

但是,要检查的另一件事是 pRoot 本身是否为 NULL

Node*  BST::searchforparentnode(Node* pRoot, int value)

    if (pRoot == NULL)
       return NULL;

    if(pRoot->pleft == NULL && pRoot->pright == NULL)
       return NULL;

    if( (pRoot->pleft != NULL && pRoot->pleft->value == value)
        || (pRoot->pright != NULL && pRoot->pright->value == value))
       return pRoot;

    if(pRoot->value > value)
       return searchforparentnode(pRoot->pleft,value);

    if(pRoot->value < value)
       return searchforparentnode(pRoot->pright,value);

【讨论】:

感谢您的帮助。我现在看到了我的问题。【参考方案2】:

你的问题是:

if(pRoot->pleft->value == value || pRoot->pright->value == value)

因为在您检查 left AND right 是否为空之前。在上面提到的部分,一个可能是空的

你可能想把你的代码改成这样:

Node*  BST::searchforparentnode(Node* pRoot, int value)

   if(pRoot->pleft == NULL && pRoot->pright == NULL)
    return NULL;

   //Added check 
   if(pRoot->pleft && pRoot->pleft->value == value)
    return pRoot;

   //Added check
   if(pRoot->pright && pRoot->pright->value == value)
    return pRoot;

   //Check also needed here
   if(pRoot->pleft && pRoot->value > value)
    return searchforparentnode(pRoot->pleft,value);

   //Check also needed here
   if(pRoot->pright && pRoot->value < value)
    return searchforparentnode(pRoot->pright,value);


恕我直言:您还可以在每个节点中创建一个指向父节点的指针。这可以大大加快某些事情的速度!

【讨论】:

谢谢。我现在明白了,我将尝试创建指向父母的指针。那肯定会加快速度【参考方案3】:
public Node nodeParent(Node root, Node n)
        if(root==null)
            return null;
        
        Node p=root;
        if(p.left==null && p.right==null )
            return null;
        
        if(p.left!=null && p.key>n.key)
            p=p.left;
            if(p.left.key==n.key)
            return p;
        
        
        if(p.right!=null && p.key<n.key)
            p=p.right;
            if(p.right.key==n.key)
            return p;
        
        
        if(p.left!=null && p.right!=null )
            if(p.key<n.key)
                p=p.right;
            else
                p=p.left;
            
        
        return p;
    

【讨论】:

【参考方案4】:

下面的代码 sn-p 应该可以解决问题:

public Node parent(Node root, int childValue)
  if(root == null)
    return null;
  Node left = root.left;
  Node right = root.right;
  if(left != null && left.value == childValue)
    return root;
  else if(right != null && right.value == childValue)
    return root;
  else if(left != null && left.value > childValue)
    return parent(left, childValue);
  else if(right != null && right.value < childValue)
    return parent(right, childValue);
   else
     return null;
 

【讨论】:

【参考方案5】:

您还可以编写此子例程的简单迭代版本,如下所示:

public Node parent(Node root, int childValue)
  Node parent = NULL;
  while(root != NULL && root.value != childValue) 
       parent=root;
       if(root.value > childValue)
         root = root.left;
       else
         root=root.right;
  
  return parent

【讨论】:

以上是关于在二叉搜索树中找到一个节点的父节点的主要内容,如果未能解决你的问题,请参考以下文章

在二叉树中找到两个节点最近公共祖先

在二叉查找树中插入节点

c++ 在二叉搜索树中删除

在二叉树中插入元素

删除二叉搜索树中的节点会引发错误

二叉树:搜索树的最小绝对差