为什么下面的代码段两次不输出 9 和输出 0 两次?



我对递归的概念很陌生,我对它的理解是,当它通过方法时,它会构建堆栈,直到满足基本情况。话虽如此,当神秘(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-1n--n-1的区别在于前者将其值更新回相同的引用n,后者返回一个新的int。

回到问题的前半部分,为什么没有输出 9?因为对于任何 n> 0 if 将被 (1) 减去 1,(2) 做一些递归,(3) 打印它,因此打印的值必须小于输入的 n 乘以 1。

为什么 0 打印 2 次?让我们打破问题,让n成为 1:

(1) 将n减去 1
n变为 0

(2)在递归中做一些递归
0 不会再减去,但还是会打印出来。 这是控制台中的第一个 0

(3)打印n(1)
打印第二个0

最新更新