【问题标题】:Recursive compare two binary search trees递归比较两个二叉搜索树
【发布时间】:2014-04-01 16:24:23
【问题描述】:

我需要比较两个二叉搜索树,看看它们是否相等。 我开发了以下使用递归的代码。

private boolean compareTrees(BinaryTreeNode n1, BinaryTreeNode n2)
{
    if(n1.getNodeData() != n2.getNodeData())
        return false;
    else
    {
        if(n1.left != null && n2.left != null)
            compareTrees(n1.left, n2.left);

        if(n1.right != null && n2.right != null)
            compareTrees(n1.right, n2.right);   
    }

    return true;
}

问题是,如果两个节点不相等,该方法将返回false,但因为我使用递归,返回值无论如何都会被覆盖为true。我整天都被这个问题困扰着,对我没有任何帮助。我在网上搜索,但没有找到与我的代码相关的任何内容。 有什么办法可以打破所有嵌套的方法并将值返回给第一个方法?

【问题讨论】:

  • 递归调用compareTrees时忘记了return关键字。

标签: java recursion binary-search-tree


【解决方案1】:

需要返回子树比较的结果:

boolean b1, b2;

if(n1.left != null && n2.left != null)
    b1 = compareTrees(n1.left, n2.left);

if(n1.right != null && n2.right != null)
    b2 = compareTrees(n1.right, n2.right);

return b1 && b2;

但为什么不事先处理nulls 呢?

private boolean compareTrees(BinaryTreeNode n1, BinaryTreeNode n2)
{
    if (n1 == null || n2 == null)
        return n1 == n2;  // i.e. both null

    if (n1.getNodeData() != n2.getNodeData())
        return false;

    return compareTrees(n1.left, n2.left) && compareTrees(n1.right, n2.right);
}

【讨论】:

  • 比我的答案更好
  • 对于任何想知道的人来说,这是一个预购比较,如果 BST 的结构和值都相同,则返回 true,这似乎是 OP 所要求的
【解决方案2】:

我会改变顺序:

private boolean compareTrees(BinaryTreeNode n1, BinaryTreeNode n2)
{
    boolean equalLeft = false;
    boolean equalRight = false;

    if(n1.getNodeData() == n2.getNodeData())
    {
        if(n1.left != null && n2.left != null){
            equalLeft = compareTrees(n1.left, n2.left);
        } else{
            equalLeft = true;
        }

        if(n1.right != null && n2.right != null){
            equalRight = compareTrees(n1.right, n2.right);
        } else{
            equalRight = true;
        }

        return equalLeft && equalRight;

    } else{

         return false;
    }
}

【讨论】:

    【解决方案3】:

    尝试避免使用 null 值并使用 equals() 方法代替 == 比较您的节点的问题。我应该这样做:

    private boolean compareTrees(BinaryTreeNode n1, BinaryTreeNode n2){
    
    //avoid nulls :TDD
    if (n1==null && n1==n2) 
        return true;
    if ((n1==null && n2!=null) || (n2==null && n1!=null)) 
        return false;
    
    //ensure logic without nulls, comparing with equals() method
    boolean areEquals =  n1.getNodeData().equals(n2.getNodeData());
    
    //compare left
    areEquals = areEquals && compareTrees(n1.left, n2.left);
    //if still equals, compare right
    if(areEquals) areEquals = areEquals && compareTrees(n1.right, n2.right);  
    
    return areEquals;
    

    }

    【讨论】:

      【解决方案4】:

      实际上,您的代码可以简化为:

      private boolean compareTrees(BinaryTreeNode n1, BinaryTreeNode n2)
      {
             if(n1==null || n2==null) return n1==n2;
             return (n1.getNodeData()==n2.getNodeDate()) && compareTrees(n1.left, n2.left) && compareTrees(n1.right, n2.right) 
      }
      

      我会告诉你你的代码存在的几个问题。

      1. root 为 null 时的终止条件(它总是在最后发生)。

      2. 递归调用中的返回语句。你最终总是返回真值。

      PS:如果你添加了NULL检查(在1中解释),你不需要在后续的递归调用中添加NULL检查。现在您的代码的后半部分将如下所示:

      return compareTrees(n1.left, n2.left) && compareTrees(n1.right, n2.right);
      

      【讨论】:

        猜你喜欢
        • 2014-01-02
        • 2021-07-03
        • 2019-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-14
        • 1970-01-01
        • 2017-05-08
        相关资源
        最近更新 更多