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

Java 为什么下面的代码段没有两次输出9和0?,java,recursion,Java,Recursion,我不熟悉递归的概念,我对它的理解是,当它通过方法时,它会构建堆栈,直到满足基本情况。尽管如此,当神秘号(9)出现时,我认为它会输出 0,1,2,3,4,5,6,7,8,9 而是输出 0,0,1,2,3,4,5,6,7,8. 我的问题是,如果堆栈应该包含神秘(9),为什么9没有被输出?为什么/如何多次输出0?当n=0时,条件不是假的吗 public static void mystery(int n) { if (n > 0) { n--; m

我不熟悉递归的概念,我对它的理解是,当它通过方法时,它会构建堆栈,直到满足基本情况。尽管如此,当神秘号(9)出现时,我认为它会输出

0,1,2,3,4,5,6,7,8,9 
而是输出

0,0,1,2,3,4,5,6,7,8. 
我的问题是,如果堆栈应该包含神秘(9),为什么9没有被输出?为什么/如何多次输出0?当n=0时,条件不是假的吗

public static void mystery(int n) {
    if (n > 0) {
        n--;
        mystery(n);
    }
    System.out.print(n + " ");
}
我的问题是,如果堆栈应该包含神秘(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--;

在将其传递给函数之前,您正在减小
n
。在

mystery(n -1);
当当前调用
神秘
进入堆栈时,
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 + " ");
因此,当它最终离开堆栈并点击打印语句时:

System.out.print(n + " ");
//n is still 9, so it will print 9
我的问题是,如果堆栈应该包含神秘(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--;

在将其传递给函数之前,您正在减小
n
。在

mystery(n -1);
当当前调用
神秘
进入堆栈时,
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 + " ");
因此,当它最终离开堆栈并点击打印语句时:

System.out.print(n + " ");
//n is still 9, so it will print 9

您的问题在于
n--

为什么? 让我们尝试
神秘(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--

为什么? 让我们尝试
神秘(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打印两次? 让我们中断问题,并将
n
设为1:

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

(2) 执行一些递归
在递归中,不会再次减去0,但仍将打印它。这是控制台中的第一个0

(3) 从(1)打印
n
首先打印第二个0

n--
等于
n=n-1
n--
n-1
之间的区别在于前者将其值更新回相同的引用
n
,后者返回一个新的int

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

为什么0打印两次? 让我们中断问题,并将
n
设为1:

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

(2) 执行一些递归
在递归中,不会再次减去0,但仍将打印它。这是控制台中的第一个0

(3) 从(1)打印
n

打印第二个0

我建议通过调试器运行此命令,可以说,查看“引擎盖下”发生了什么,或者在paperTry上执行替换
n--;神秘(n)具有
神秘性(n-1)@Andreas我做了,它输出了我预测的结果。我的问题是n--;不同于神秘(n-1);“它不是在做同样的事情吗?”GBlodgett我在纸上手工画了出来,但我一定是做错了,因为我得到了错误的输出。我只是不知道为什么错了。n--;,有什么特别之处;?与神秘(n-1)相反?1)神秘(9)->若语句检查9>0为真,则n--;现在表示n=8,stack.push(8)2)神秘(8)->若语句检查为8>0 true,则n--;n=7,堆栈推送(7)。。。9) 神秘(1)->1更大