【问题标题】:Recursively searching binary tree issue递归搜索二叉树问题
【发布时间】:2012-08-04 13:20:59
【问题描述】:

我已经编写了以下代码用于递归搜索二叉树。 即使我的 system.out 语句正在执行,return 语句也没有从整个递归中返回,因此该方法没有返回 true。

谁能建议我如何退出整个递归?

public static boolean isElementinTree(int num, BinaryTreeNode root) 
{
    if (root != null)
    {
        int rootVal = root.getData();
        BinaryTreeNode left = root.getLeft();
        BinaryTreeNode right = root.getRight();
        if (left != null)
        {
            isElementinTree(num,left);

        }
        if (right != null)
        {
            isElementinTree(num,right);
        }
        if (num == rootVal)
        {
            System.out.println("------ MATCH -----");               
            return true;
        }           
    }   
    return false;
}

【问题讨论】:

  • 我认为你应该先检查节点中的数据是否匹配,如果不匹配,你应该移动到左边或右边的子树。

标签: java search recursion tree binary-tree


【解决方案1】:

这样的简单解决方案有什么问题:

public static boolean isElementinTree(int num, BinaryTreeNode root)
{
    return root != null &&                           //The tree is non-null
           (num == root.getData() ||                 //We have num in this node OR
            isElementInTree(num, root.getLeft()) ||  //We have num in left subtree OR
            isElementInTree(num, root.getRight()) ); //We have num in right subtree
}

【讨论】:

    【解决方案2】:

    递归解:

    boolean isElementinTree (int num, BinaryTreeNode root)
    {
      if(root == null)
       return false;
    
      if(root.value == num)
       return true;
    
      boolean n1 = isElementinTree(num,root.getLeft());
      boolean n2 = isElementinTree(num,root.getRight());
    
      return n1 ? n1 : n2;
    
    }
    

    【讨论】:

      【解决方案3】:

      如果您确实在左子树或右子树中找到了要查找的元素,则需要将此事实返回给调用者:

          if (left != null)
          {
              if(isElementinTree(num,left)) return true;
          }
          if (right != null)
          {
              if(isElementinTree(num,right)) return true;
          }
      

      只有在左树、右树和当前节点都没有找到它时,你最终才会落入最终的return false

      【讨论】:

        【解决方案4】:

        您需要检查该值是否在其中一个分支中,并保存该结果。

        初始化变量boolean found = false;

        当您进行递归调用时,您需要执行以下操作:

        found = isElementinTree(num,left)
        

        右侧也一样。

        最后,不是返回false,而是检查是否在分支上找到了值,只需return found;

        另外,首先检查您要查找的号码是否不在节点本身上,而不是先搜索每个分支。只需切换 if 的顺序。

        【讨论】:

          【解决方案5】:

          这就是问题所在:

          if (left != null)
          {
              isElementinTree(num,left);
          
          }
          if (right != null)
          {
              isElementinTree(num,right);
          }
          

          在这些情况下,您正在 调用该方法 - 但忽略了结果。我怀疑您只是想更改其中的每一个以在发现时立即返回:

          if (left != null && isElementinTree(num, left))
          {
              return true;
          }
          if (right != null && isElementinTree(num, right))
          {
              return true;
          }
          

          或者为了让整个事情更具声明性,你可以做得更简单:

          public static boolean isElementinTree(int num, BinaryTreeNode root) 
          {
              return root != null && (root.getData() == num ||
                                      isElementInTree(num, root.getLeft()) ||
                                      isElementInTree(num, root.getRight()));
          }
          

          使用 null 第二个参数调用 isElementInTree 很好,因为您已经在第一部分中防止了这种情况。

          【讨论】:

          • 对于树右半部分的元素永远不会返回 true
          • 那只会搜索第一个分支,还是我遗漏了什么?
          • @pcalcao:见我的第二次编辑。全身塌陷成三行:)
          • 很好,你有我的支持。简洁且不牺牲太多可读性。
          • 我想说三行版本的可读性更多,因为它准确地捕捉到了算法的本质——如果它与根节点,或在左子树中,或在右子树中。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-01-02
          • 2021-07-03
          • 2019-04-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-14
          相关资源
          最近更新 更多