【问题标题】:Java return boolean true using recursionJava使用递归返回布尔值true
【发布时间】:2021-08-08 02:45:56
【问题描述】:

我正在尝试查看我的二叉搜索树中是否包含一个值,并且我正在使用递归遍历该树。问题是函数返回 false 作为调用堆栈上的最后一个值,而不是 true。

这是伪代码:

public boolean containsValue(Node node, Value v) {

   if (node.value.equals(v)) {
     return true;
   } 
   containsValue(node.left, v); // <- search left tree
   containsValue(node.right, v); // <- search right tree

   return false;
}

这总是返回 false。

但是我不能这样做,因为第二个 return 语句是死代码:

 return containsValue(node.left, v);
 return containsValue(node.left, v);

那么我该如何解决这个问题?

【问题讨论】:

    标签: java recursion


    【解决方案1】:

    这解决了眼前的问题,但不是搜索二叉树的正确或有效方法,因为它不决定向左还是向右,它只是笨拙地向左然后向右。正确答案是here


    如果左节点包含它或 (||) 右节点包含它,您希望返回 true。

    return containsValue(node.left, v) || containsValue(node.right, v);
    

    请注意,如果左侧包含它,它将短路并且不会向右看。

    你甚至可以制作整个东西:

    return node.value.equals(v) ||
           containsValue(node.left, v) ||
           containsValue(node.right, v);
    

    【讨论】:

    • 这是不正确的实现,用于查看二叉搜索树。根据定义,二叉搜索树的值越左越小,越右越大,这种方法没有利用这个属性,使得搜索效率更低。
    • @nickzoum 你说的很对!我解决了提出的直接问题,并没有考虑到它是一棵有组织的树。一旦您接受 OP 更改,我什至会删除。
    • @Kingamere 请将接受的答案更改为 nick's。
    • 谢谢,但您可以编辑您的答案以使其正确。
    • @nickzoum 我可以但不,你应得的!
    【解决方案2】:

    你来了

    public boolean containsValue(Node node, Value value){
        int result = node.value.compareTo(value);
        if(result == 0){
            return true;
        }else if(result < 0){
            if(node.left != null){
                return containsValue(node.left, v);
            }
            return false;
        }else{
            if(node.right != null){
                return containsValue(node.right, v);
            }
            return false;
        }
    }
    

    这将检查当前节点的值与参数值的比较情况。如果参数值较小则返回左孩子(&lt;0)的结果,如果相同则返回true(==0),如果传递的值较大则返回右孩子(&gt;0)的结果。这将一直持续到找到一个值或需要搜索的子项为 null。

    此方法完全利用二叉搜索树,因为它不检查所有变量,并且平均效率为 O(log(n)),而仅查看通过所有节点的平均效率为 O(n),这是最差的。

    旁注: 获取具有该值的节点的方法本质上是相同的,您只需将true 替换为node,将false 替换为null,将boolean 替换为Node

    例子:

    public Node getNode(Node node, Value value){
        int result = node.value.compareTo(value);
        if(result == 0){
            return node;
        }else if(result < 0){
            if(node.left != null){
                return containsValue(node.left, v);
            }
            return null;
        }else{
            if(node.right != null){
                return containsValue(node.right, v);
            }
            return null;
        }
    }
    

    【讨论】:

      【解决方案3】:

      您可以检查任一分支是否返回 true,并在尝试返回 false 之前将其传递。

      public boolean containsValue(Node node, Value v) {
      
         if (node.value.equals(v)) {
             return true;
         } else if (containsValue(node.left, v)) {
             return true;
         } else if (containsValue(node.right, v)) {
             return true;
         }
      
         return false;
      }
      

      【讨论】:

        【解决方案4】:

        有些人喜欢单行:

        public boolean containsValue(Node node, Value v) {
            return node.value.equals(v) || containsValue(node.left, v) || containsValue(node.right, v);
        }
        

        【讨论】:

          【解决方案5】:
            public boolean containsValue(Node node, Value v) {
          
             if (node.value.equals(v)) {
               return true;
             } 
             else if(containsValue(node.left, v))
               return true; // <- search left tree
          
             else if(containsValue(node.right, v)) // <- search right tree
              return true;
          
             return false;
          }
          

          目前,您的函数也返回 true,但仅针对与搜索值匹配的节点,对于所有其他节点,它将返回 false。因此,当在调用堆栈中向后/或向上移动时,它最终返回 false 作为最终答案。只有在树中有一个节点并且匹配搜索值的情况下才会正确。

          【讨论】:

            【解决方案6】:

            由于其递归性质,该方法返回 false。在找到值后的递归函数中,它会将值返回给方法的父副本,然后根据代码返回其父副本。我们需要以某种方式存储结果,以便将其带到递归方法的第一次调用中。

            简单来说,我们需要将结果存储在一个变量中,并将该变量作为递归函数的最终值返回。

            对于程序员,我正在分享一个代码,以帮助并深入理解它。

             public boolean contains (int i){
                boolean result= false;
                boolean flag = recursiveContains(root, i, result);
                System.out.println(flag);
                return flag;
            }
            public boolean recursiveContains(Node root, int i, boolean result)
            {
                // if root not null
                if (root != null){
                    // if i value found in RandomBST
                    if (root.value == i) {
                        result = true; // result is used for understanding
                        return result;
                    }
                    else if (i < root.value) {
                        //if i smaller then root.value search i in leftchild
                        result = recursiveContains(root.left, i, result);
                    } else { 
                        //if i>root.value search for i in rightchild
                        result = recursiveContains(root.right, i, result);
                    }
                }
                return result;
            }
            

            此外,我正在添加代码的图片说明。但这需要专注。我已经为 i=9 调用了上述函数。并展示了它如何返回 true。它总共创建了 3 次 contains 方法的调用。

            enter image description here

            【讨论】:

              猜你喜欢
              • 2018-08-02
              • 1970-01-01
              • 2015-04-12
              • 1970-01-01
              • 2015-12-27
              • 2015-02-08
              • 2021-01-06
              • 1970-01-01
              • 2022-11-12
              相关资源
              最近更新 更多