【问题标题】:Why my recursion doesnt work? (Java)为什么我的递归不起作用? (爪哇)
【发布时间】:2014-07-21 19:50:21
【问题描述】:

我想找到二叉树的最低共同祖先(不是二叉搜索树!)为此,我使用此网页中的第二种方法:http://www.geeksforgeeks.org/lowest-common-ancestor-binary-tree-set-1/ 基本上,在 Java 中,我的方法如下所示:

  private static int LCA2(Node root, Node n1, Node n2)
  {
    if(root == null) return -1;

    if(root.id == n1.id || root.id == n2.id) return root.id;

    int left = LCA2(root.left, n1, n2);
    int right = LCA2(root.right, n1, n2);

    if(left != -1 && right != -1) return root.id;

    if(left != -1) return LCA2(root.left, n1, n2);

    return LCA2(root.right, n1, n2);
}

这是main()函数:

   public static void main (String[] args)
   {
        List<Node> tree = new ArrayList<Node>();

        Node n1 = new Node(1);
        Node n2 = new Node(2);
        Node n3 = new Node(3);
        Node n4 = new Node(4);
        Node n5 = new Node(5);
        Node n6 = new Node(6);
        Node n7 = new Node(7);
        Node n8 = new Node(8);
        Node n9 = new Node(9);

        n1.left = n2;
        n1.right = n3;
        n2.left = n4;
        n2.right = n5;
        n5.left = n6;
        n3.left = n8;
        n3.right = n7;
        n8.right = n9;

        res = new ArrayList<Integer>();
        int k = 2;

//      findKNodes(n1, k);
//      for (int i = 0; i < res.size(); i++)
//          System.out.print(res.get(i) + " ");

        int res = LCA2(n1, n4, n6);

        System.out.println(res);

    }

基本上我的树是这样的:

    1
   / \
  2   3
 / \  /\
4  5  8 7
  /   \
 6     9

然后我运行递归函数LCA(Node root, node n1, node n2),root = 1, n1 = 4, n2 = 6;所以在第一次递归调用LCA 之后,我希望函数返回left = 4right = -1 并在根的左子树上递归。但是它返回left = 6right = -1,这对于第一次迭代来说不是问题,但是对于下一次它会进入无限循环,我不知道如何解决这个问题。

编辑:类节点的代码:

public static class Node
{
    int id;
    Node left;
    Node right;

    public Node (int id)
    {
        this.id = id;
    }
}

【问题讨论】:

  • 这是否正确:n5.left = n6;?另外,你有 n1.right = n3;在 sn-p 中两次。
  • 是的,n5.left = n6;我将删除第二个 n1.right = n3
  • 根据你的树,这不正确。
  • @user3371223 好的,但是用相同的输入参数再次调用 LCA2 是没有意义的。您已经计算了该值,并将其存储在您的变量 left 中。
  • 嗯,你的代码在我的电脑上运行正常,删除这行res = new ArrayList&lt;Integer&gt;();

标签: java algorithm recursion tree


【解决方案1】:

注意:在解决了重新编译代码的问题(我在评论中提到过)之后,这里是帮助您的代码运行得更快的提示。

为避免两次调用相同的方法LCA2,您应该将方法重写如下:

private static int LCA2(Node root, Node n1, Node n2)
{
    if(root == null)
        return -1;

    if(root.id == n1.id || root.id == n2.id)
        return root.id;

    int left = LCA2(root.left, n1, n2);
    int right = LCA2(root.right, n1, n2);

    if(left != -1 && right != -1)
        return root.id;

    if(left != -1)
        return left; // you don't need to call the same routine again here, which will cost you some time.

    return right; //Similar reason

}

【讨论】:

    【解决方案2】:

    @Khaled 和@Pham Trung 已经给你答复了,但让我帮你清除递归调用跟踪。

        1. LCA2(1, 4, 6) -> left = LCA2(2, 4, 6) = 2 (by 2 step because left = 4 != -1 and right = 6 != -1 means root.id is LCA which is 2)
                            right = LCA2(3, 4, 6) = -1 
    
        2. LCA2(2, 4, 6) -> left = LCA2(4, 4, 6) = 4 (by 2a step)
                            right = LCA2(5, 4, 6) = 6 (by 2b step)
    
        2a. LCA2(4, 4, 6) -> return root.id which is 4
        2b. LCA2(5, 4, 6) -> left = LCA2(6, 4, 6) = 6(by 2ba step)
                             right = LCA2(null, 4, 6) = -1  
    
        2ba. LCA2(6, 4, 6) -> return root.id which is 6
    

    作为最终调用 2 != -1 所以它返回 2 作为答案。
    如果您需要更多说明,请回复。 如果遇到困难,可以在以下 URL 中找到 geeksforgeeks 的树问题的 java 代码。 https://github.com/harmishlakhani/AlgoAndDataStructure/blob/master/AlgoAndDataStructure/src/com/ds/tree/BinaryTreeUtility.java

    【讨论】:

    • 非常感谢!这正是我所需要的!
    猜你喜欢
    • 1970-01-01
    • 2015-06-29
    • 2017-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-19
    • 1970-01-01
    • 2020-08-18
    相关资源
    最近更新 更多