java在处理递归时如何创建和传递参数?[duplicate]

7ajki6be  于 2023-03-11  发布在  Java
关注(0)|答案(1)|浏览(135)

此问题在此处已有答案

(93个答案)
9小时前关门了。
以寻找二叉树的最大深度为例(二叉树的最大深度是从根节点到最远叶节点的最长路径沿着的节点数)。
下面的代码是代码的一部分,每一次递归调用,depth的值都会被上一级函数的depth++修改,但是当函数结束返回到上一级函数时,不需要执行depth--,甚至depth+=100也可以完美运行。
IntelliJ将提示“在depth += 100处更改的值将永远不会被使用”。尽管如此,该行仍将执行,但更改是徒劳的。
那么在JVM中发生了什么?变量depth实际上在堆栈内存中创建了多少次?是每次调用函数时都创建一个新的int depth?还是所有函数都有指向同一个int depth的变量?如果是前者,那么我认为depth--应该是必要的,如果是后者,那么我认为每次进入下一级递归时,传入的depth只能是0,所以现在我很困惑。
这是我在stackoverflow的第一个问题,我的英语还不如一个母语为英语的人,希望我的描述足够清楚,感谢任何关心这个问题的人,我很感激你们的帮助!

public static void max(TreeNode root,int depth){
        if(root == null) return;
        depth ++
        max(root.left,depth);
        max(root.right,depth);
        depth += 100;
    }
yzuktlbb

yzuktlbb1#

首先,代码并没有完成所描述的工作,初始调用者不会得到树的深度,函数将白白完成所有这些工作。
关于你的评论和问题:
IntelliJ会提示“在深度+= 100处更改的值将永远不会被使用”。
这是真的,因为在该语句之后,函数的执行上下文被破坏,变量depth不再存在--用于它的内存被释放。
变量depth在堆栈内存中实际创建了多少次?是否每次调用函数时都创建一个新的int depth?
是的,每次调用函数时都会创建一个新的int depth,它是一个函数执行上下文的 * 本地 * 变量:它在函数开始执行时被创建,通过分配由调用者提供的值而被初始化,并且在函数返回时被销毁。
......那么我认为depth--应该是必要的。
不。在函数执行结束时,depth变量将不再存在,所以在“最后一刻”给它赋值毫无意义。除了即将结束的当前执行上下文,没有人会查看该变量。
请注意,调用方的depth变量与被调用方的depth变量没有任何关系。对后者的赋值(如=+=++)对前者没有影响。调用方的depth变量不会(也不能)通过将其作为参数传递给函数调用而被赋值。
解决方法是使用函数return深度:

public static int max(TreeNode root) { // No depth parameter!
        if(root == null) return 0;
        // Get the depths returned by recursive calls and derive a
        //    new depth-value from those, and return that to caller
        return 1 + Math.max(max(root.left), max(root.right));
   }

相关问题