【问题标题】:Removing a child from a tree从树上移走一个孩子
【发布时间】:2021-11-26 09:14:38
【问题描述】:

如果我检查 children 是否包含 childToRemove,为什么我需要另一个 else 来检查孩子是否在 this.children 中?

 public void removeChild(TreeNode childToRemove)
  {
           if(this.children.isEmpty())
           {
             return ;
           }
           else if(this.children.contains(childToRemove))
           {
               this.children.remove(childToRemove);
               return;
           }
           else
           {
             for(TreeNode child : this.children)
             {
                 child.removeChild(childToRemove);
             }
           }
  }

【问题讨论】:

  • children 的类型是什么?如果是ArrayList,则不需要这样做。
  • 因为这个方法是递归删除...这意味着即使它不是直接的孩子,而是孩子的孩子也应该被删除...第一个分支(isEmpty)处理没有孩子的小事。第二个(children.contains)照顾直接孩子......而最后的“else”分支递归地照顾间接孩子(孩子的孩子......)。
  • @Renato,谢谢你帮助我理解。
  • 没问题。 @mario 你被否决了,因为你的问题缺乏上下文......比如:这段代码来自哪里,周围的类是什么,你为什么需要知道这个,children 的类型是什么等等......能够正确回答我们需要知道所有这些。例如,我不得不猜测childrenList<TreeNode>,并且围绕此方法的类也是TreeNode 类型。但如果这些假设是错误的,我的解释就会不正确。
  • 请将此问题移至parenting.stackexchange.com(对不起,我无法抗拒)。 :D

标签: java data-structures


【解决方案1】:

正如我在 cmets 中所写,我假设:

  • 此方法在TreeNode 类中。
  • this.children 的类型为 List<TreeNode>

即这是一个基本的树数据结构。

我还将假设一个孩子可能只在树中出现一次。如果它可以出现多次,这将是一个图表,而不是一棵树。

鉴于这些假设,这种方法是有缺陷的,应该写成如下(用 cmets 解释原因):

/**
 * Remove the given node from this TreeNode.
 *
 * @param childToRemove the child to be removed
 * @return true if the child was removed, false otherwise.
 */
public boolean removeChild(TreeNode childToRemove)
{
           // if this tree is empty, there's nothing to do
           if(this.children.isEmpty())
           {
             return false;
           }

           // there's no point checking with "contains", just try
           // to remove the child, and if that succeeds, we're done.
           if (this.children.remove(childToRemove)) 
           {
             return true;
           }

           // the child is not a direct child of this TreeNode, but it
           // may be an indirect child, i.e. a descendant of this node,
           // so we need to try every single descendant in this tree,
           // stopping as soon as we find it to avoid wasting time.
           for(TreeNode child : this.children)
           {
               if (child.removeChild(childToRemove))
               {
                   return true;
               }
           }

           // we couldn't find the node anywhere, so it couldn't be removed.
           return false;
}

另外,因为这个方法正在删除任何后代,而不仅仅是直接孩子(孩子通常只是一个直接孩子,对吗?间接孩子是孙子,孙孙等),我会重命名该方法为了让这一点更明显,比如removeNoderemoveDescendant

【讨论】:

    猜你喜欢
    • 2012-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-18
    • 2011-11-03
    • 1970-01-01
    相关资源
    最近更新 更多