Java 一直在理解递归

Java 一直在理解递归,java,algorithm,recursion,Java,Algorithm,Recursion,在过去的几个小时里,我一直试图理解为什么这个程序的输出行为如此怪异。递归函数的第一部分对我来说很有意义,但是,不幸的是,我发现其余部分非常混乱 我想知道为什么程序会倒退,甚至添加到一个应该被减去的变量。这对我来说毫无意义。谢谢你的帮助 这是我的递归函数: public static void threeWays(int id, int n) { if (n >= 0) { System.out.println(id + "=" + n);

在过去的几个小时里,我一直试图理解为什么这个程序的输出行为如此怪异。递归函数的第一部分对我来说很有意义,但是,不幸的是,我发现其余部分非常混乱

我想知道为什么程序会倒退,甚至添加到一个应该被减去的变量。这对我来说毫无意义。谢谢你的帮助

这是我的递归函数:

public static void threeWays(int id, int n) {
    if (n >= 0) {
        System.out.println(id + "=" + n);
        threeWays(id + 1, n - 1);
        threeWays(id + 1, n - 2);
        threeWays(id + 1, n - 3);
    }
}

public static void main(String[] args) {
    threeWays(1, 4);
}
以下是输出:

  4
    3
      2
        1
          0
        0
      1
        0
      0
    2
      1
        0
      0
    1
      0
1=4

2=3

3=2

4=1

5=0

4=0

3=1

4=0

3=0

2=2

3=1

4=0

3=0

2=1

3=0

Python3版本:

  def threeWays(f, i, n):
      if n >= 0:
          print(f, i, '=', n)
          threeWays('1st', i + 1, n - 1)
          threeWays('2nd', i + 1, n - 2)
          threeWays('3rd', i + 1, n - 3)

  threeWays('    ', 1, 4)

乍一看,它可能看起来像DFS,但实际上不是

当从第二个和第三个
threeWays
递归调用
threeWays
时,第一个或第一个和第二个
threeWay
(s)也被称为

threeWays('   ', 1, 4)            ->     1 = 4
  threeWays('1st', 2, 3)          -> 1st 2 = 3
    threeWays('1st', 3, 2)        -> 1st 3 = 2
      threeWays('1st', 4, 1)      -> 1st 4 = 1
        threeWays('1st', 5, 0)    -> 1st 5 = 0
          threeWays('1st', 6, -1)
        threeWays('2nd', 5, -2)
        threeWays('3rd', 5, -3)
      threeWays('2nd', 4, 0)      -> 2nd 4 = 0
      threeWays('3rd', 4, -1)
    threeWays('2nd', 3, 1)        -> 2nd 3 = 1
      threeWays('1st', 4, 0)      -> 1st 4 = 0
      threeWays('2nd', 4, -1)
      threeWays('3rd', 4, -2)
    threeWays('3rd', 3, 0)        -> 3rd 3 = 0
...

如果缩进输出以显示调用堆栈在每个点的深度,您可能会发现它更有用。我用
System.out.println(“”).repeat(id)+n替换了您的打印语句并收到输出:

  4
    3
      2
        1
          0
        0
      1
        0
      0
    2
      1
        0
      0
    1
      0

这里的结构是,每次打印一个数字时,下一级将按降序显示下面的三个数字,直到它变为零。这正是函数所做的

我的建议是:在一张纸上写出递归调用树。这是这里所有人真正能为你做的。我已经画了表,但我似乎无法理解最初调用函数时在后台发生了什么。所以,我真的不知道该怎么做。要理解递归,你必须理解递归。程序没有倒退,递归正在展开。通过一个调试器来运行它可能更容易,并且用笔和纸仔细地一步一步地完成每个函数调用,以了解发生了什么,简化事情只需三种方式调用
(id+1,n-1)而不是其他两个调用。下面是开始调试的一个好方法:。分叉并开始调试代码,确保检查堆栈。我在这里做了一个示例演示,非常感谢您的帮助!但我仍然无法理解这些数字是如何按这样的顺序打印的,以及这些数字是如何发生如此剧烈的变化的(即,前5=0到第2 4=0)。