繁体   English   中英

在递归调用期间,方法的参数如何存储在堆栈中?

[英]How does parameters of a method get stored in stack during a recursive call?

我正在做一个 leetcode 问题https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree-ii/ ,我对在递归调用期间如何存储方法的参数感到困惑。

如果一个节点被访问,我想保存它被访问的状态。 当我发送两个变量时,当堆栈展开时,更新的变量值将丢失。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        boolean val1 = false, val2 = false;
        System.out.println("val1 - "+val1+" val2 - "+val2);
        System.out.println();

        TreeNode node = lca(root, p, q, val1, val2);
        System.out.println();
        System.out.println("val1 - "+val1+" val2 - "+val2);

        if(val1==true && val2==true)
            return node;
        return null;
    }
    
    private TreeNode lca(TreeNode root, TreeNode p, TreeNode q, boolean val1, boolean val2) {
        if(root==null) 
            return root;
        else if( p==root){
            val1 = true;
            System.out.println("val1 - "+val1+" val2 - "+val2);
            return root;
        } 
        else if( root==q){
            val2 = true;
            System.out.println("val1 - "+val1+" val2 - "+val2);
            return root;
        } 

        TreeNode left = lca(root.left, p, q, val1, val2);
        TreeNode right = lca(root.right, p, q, val1, val2);
        
        if(left==null && right==null) return null;
        else if(left==null) return right;
        else if(right==null) return left;
        else return root;
    }
}

Output -
val1 - false val2 - false

val1 - true val2 - false
val1 - false val2 - true

val1 - false val2 - false

但是,如果我发送一个数组并更新数组内的值,并在递归期间将数组本身作为参数传递,那么更新的变量值将被持久化。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        boolean res[] = new boolean[2];
        //boolean val1 = false, val2 = false;
        System.out.println("val1 - "+res[0]+" val2 - "+res[1]);
        System.out.println();

        TreeNode node = lca(root, p, q, res);
        System.out.println();
        System.out.println("val1 - "+res[0]+" val2 - "+res[1]);

        if(res[0]==true && res[1]==true)
            return node;
        return null;
    }
    
    private TreeNode lca(TreeNode root, TreeNode p, TreeNode q, boolean res[]) {
        if(root==null) 
            return root;
        else if( p==root){
            res[0] = true;
            System.out.println("val1 - "+res[0]+" val2 - "+res[1]);
            return root;
        } 
        else if( root==q){
            res[1] = true;
            System.out.println("val1 - "+res[0]+" val2 - "+res[1]);
            return root;
        } 

        TreeNode left = lca(root.left, p, q, res);
        TreeNode right = lca(root.right, p, q, res);
        
        if(left==null && right==null) return null;
        else if(left==null) return right;
        else if(right==null) return left;
        else return root;
    }
}

Output - 

val1 - false val2 - false

val1 - true val2 - false
val1 - true val2 - true

val1 - true val2 - true

我觉得我在这里缺少一些基本知识,谁能帮助我了解这两个代码的不同之处以及我可以阅读的任何材料以提高我对堆栈和递归的了解?

这个问题与“递归”关系不大,而与函数调用本身有关。

当您调用foo(var1, var2)时,变量按 value 传递 您在功能块内所做的更改不会传播到功能之外。

当你传递数组时,它通过引用/指针传递。 对其进行的任何修改都是对它的实际内存进行的,因此即使在功能块之外,更改也会保留/反映。

您可以在此处阅读有关按值传递和引用之间的区别的更多信息。

编辑:
Java“总是”按值传递,因为对象具有按值传递的引用。 这个令人困惑的术语在这里详细说明。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM