我对递归的概念很陌生,我对它的理解是,当它通过方法时,它会构建堆栈,直到满足基本情况。话虽如此,当神秘(9)时,我以为它会输出
0,1,2,3,4,5,6,7,8,9
而是输出
0,0,1,2,3,4,5,6,7,8.
我的问题是,如果堆栈应该包含 mystery(9),为什么不输出 9,为什么/如何多次输出 0?当 n = 0 时,条件不是假吗?
public static void mystery(int n) {
if (n > 0) {
n--;
mystery(n);
}
System.out.print(n + " ");
}
我的问题是,如果堆栈应该包含 mystery(9),为什么没有输出 9,为什么/如何多次输出 0?
合乎逻辑的是,n
接近于零。但是,递归在n =< 0
时停止。因此,让我们跳过所有递归调用,直到n==1
。
n
大于零,因此会递减。n == 0
.下一次调用n
不大于零,因此递归停止并打印出n
。
0
然后最后一个调用从堆栈中出来。请记住,您在通话前递减了n
,因此也0
。
0 0
然后所有其他调用以相同的方式从堆栈中发出:
0 0 1 2 3 4 5 6 7 8
9
永远不会打印,因为您在递归调用之前减去n
。
两者之间的区别:
n--;
和
mystery(n-1);
是您在将n
传递给函数之前正在减少它。在
mystery(n -1);
当mystery
的当前调用进入堆栈时,n
仍然是传入时的状态。或者在9
的例子中:
if (n > 0) {
//n is not changed here. It is still 9
mystery(n -1); //Passes 8 to mystery
}
System.out.print(n + " ");
因此,当它最终从堆栈中出来并点击 print 语句时:
System.out.print(n + " ");
//n is still 9, so it will print 9
你的问题在于n--
.
为什么?
让我们尝试mystery(1)
作为基本解释。
mystery(1) {
if (1 > 0) {
1--;
mystery(0);
}
System.out.print(0 + " ");
}
你现在明白为什么了吗?
您不能修改期望它保持不变的n
。
尝试将其替换为:
public static void mystery(int n) {
if (n > 0) {
mystery(n - 1); //minusByOne and pass it to the next call
}
System.out.print(n + " "); // n itself stays the same
}
首先,n--
等于n=n-1
。n--
和n-1
的区别在于前者将其值更新回相同的引用n
,后者返回一个新的int。
回到问题的前半部分,为什么没有输出 9?因为对于任何 n> 0 if 将被 (1) 减去 1,(2) 做一些递归,(3) 打印它,因此打印的值必须小于输入的 n 乘以 1。
为什么 0 打印 2 次?让我们打破问题,让n
成为 1:
(1) 将n
减去 1n
变为 0
(2)在递归中做一些递归
0 不会再减去,但还是会打印出来。 这是控制台中的第一个 0
(3)打印n
(1)
打印第二个0