簡體   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