所以,这是代码:
package rekurzija;
public class exkurzija {
public static void main(String[] args) {
myMethod(4);
}
static void myMethod( int counter)
{
if(counter == 0)
return;
else
{
System.out.println("hello" + counter);
myMethod(--counter);
System.out.println(""+counter);
return;
}
}
}
这是输出:
hello4
hello3
hello2
hello1
0
1
2
3
现在,我试图理解这一点,尝试谷歌搜索这个问题,但没有用。我无法找到与此有关的协议。 所以更具体一点,我理解为什么会发生这种情况:
hello4
hello3
hello2
hello1
但我绝对不明白为什么会这样:
0
1
2
3
如果有人能解释为什么最终它会增加,为什么它不会继续减少,我将非常感激?
答案 0 :(得分:4)
以下是递归的顺序。每个级别的缩进表示更深的呼叫。
myMethod(4)
. counter is 4
. print "hello4"
. counter-- and is now 3
. myMethod(3)
. . counter is 3
. . print "hello3"
. . counter-- and is now 2
. . myMethod(2)
. . . counter is 2
. . . print "hello2"
. . . counter -- and is now 1
. . . myMethod(1)
. . . . counter is 1
. . . . print "hello1"
. . . . counter-- and is now 0
. . . . myMethod(0)
. . . . . counter is 0
. . . . . return
. . . . print counter "0"
. . . . return
. . . print counter "1"
. . . return
. . print counter "2"
. . return
. print counter "3"
. return
要回答OP的问题,最后由于代码行而打印0/1/2/3:
System.out.println(""+counter);
请注意,这会在每个递归级别调用,这由计数器指示。
答案 1 :(得分:3)
您的递归电话:
myMethod(--counter);
...发生在代码中,要在方法中执行。因此,挂起的方法然后被放入堆栈并等待递归调用完成,此时方法然后以与它们被添加到堆栈的方式相反的顺序完成。因此,第一次通过该方法检查零值并且没有发现它们打印“hello4”然后该方法的实例进入堆栈,而下一个实例从myMethod(--counter);
行调用。该实例的值与3相同,然后是2,然后是1.此时检测到零值并且递归停止,然后代码开始回调您已经推入堆栈的方法,因为它们不完整,即:他们还没有遇到任何返回指令,他们坐在那里等着指示:
System.out.println(""+counter);
然后你的方法遇到最后一条返回指令并完成。
因此,如果您打算将“hello4”等打印而不是打印底部,那么myMethod(--counter);
所示的行应为:
return myMethod(--counter);
答案 2 :(得分:2)
理解递归的方法是展开它。
static void myMethod( int counter) { if(counter == 0) { return; } else { System.out.println("hello" + counter); myMethod(--counter); System.out.println(""+counter); return; } }
以上是您修改格式的原始功能。在进一步讨论之前,我想稍微简化它。
static void myMethod(int counter) {
if(counter > 0) {
System.out.println("hello" + counter);
counter -= 1;
myMethod(counter);
System.out.println(""+counter);
}
}
逻辑被简化了,但是这个方法完成了所有相同的事情(除了它确实允许自己必须包含负数,如果给出负输入)。
我已经对此进行了简化,因为我想在原始参数为2的情况下解开它。我们将打开整个堆栈,并按照执行的顺序轻松跟踪代码。发生了什么事。
int counter2 = 2; // assume we called your method with an argument of 2
if(counter2 > 0) { // it is, it's 2
System.out.println("hello"+counter2); // "hello2"
counter2 -= 1; // counter2 is now 1
// enter recursive call
int counter1 = counter2; // the recursive call has a different scope
if(counter1 > 0) { // it is, it's 1
System.out.println("hello"+ counter1); // "hello1"
counter1 -= 1; // counter1 is now 0
// enter recursive call
int counter0 = counter1; // the recursive call has a different scope
if(count0 > 0) { // it is not, do nothing
}
// exit recursive call
System.out.println(""+counter1); // we're still in one layer of recursion, this prints 0
}
// exit recursive call
System.out.println(""+counter2); // this prints 1
}
// exit function
这种模式应该很清楚。以4作为起始参数,模式只有两层深度。
这里要记住两件重要的事情。
你方法的要点是:
"hello"+counter
。myMethod
。counter
如果我们取消第三步,我们就不再做任何递归的事了。因此,我们会更直观地看到更符合逻辑的东西。但是对于每一层递归,我们必须用步骤1到步骤4替换步骤3.因此对于一层递归,步骤的顺序变为:
"hello"+counter
。"hello"+counter
。myMethod
。counter
counter
要添加另一个图层,我们再次将步骤3替换为步骤1-4。
"hello"+counter
。"hello"+counter
。"hello"+counter
。myMethod
。counter
counter
counter
这个模式重复变得越来越嵌套,直到你遇到你的基本情况(counter == 0)或最终遭遇堆栈溢出异常。
当我们遇到基本案例时,第3步看起来像这样:
"hello"+counter
。"hello"+counter
。"hello"+counter
。counter
counter
counter