有人可以解释一下Java递归的工作原理,特别是在下面的程序中?

时间:2019-12-12 03:45:04

标签: java recursion

下面的代码的每一行做什么?我对Java还是很陌生,很难理解递归。

std::atomic<>

2 个答案:

答案 0 :(得分:0)

在您的代码中,reversePrint中的print语句应如下所示,

System.out.println(numbers[numbers.length - 1] + ""); // for printing from left -> right

递归可能会使许多人感到困惑。让我尽力解释。

您可能已经知道,递归编程基本上包含一种方法,该方法会重复调用自身直到满足特定条件。注意这一点,

  

直到满足特定条件

。这对于停止方法的连续执行非常重要,这可能导致StackOverflow异常。

好吧,在递归方法中,您需要做的第一件事是检查是否继续执行或返回控制语句。

为简单起见,让我们仅将10,20作为示例代码的输入。

  1. 首先,main方法为以下方法调用递归(recursivePrint)方法: 打印元素。
  2. 正如我之前所说,在
  3. reversePrint方法内部,您正在通过检查数组中的元素数来检查是否继续或返回控件。这是因为如果数组中没有元素,那么继续执行程序就没有意义。
  4. 接下来,您准备通过减小数组大小(当前数组大小-1)来准备传递给reversePrint方法的下一组数组。在第二点,您将10,20作为数组中的两个元素。现在,您要构建一个以10为元素的新数组(这里的想法是将各个元素从右到左分开,以便您可以从右到左打印它),然后将其传递给{{1 }} 方法。 要记住的事情: 仍然留下一些代码来打印最后一个元素(reversePrint),该元素将在此递归方法调用完成后执行
  5. 检查数组是否为空,因为我们有10个元素,所以构造具有零个元素或空数组(20)的新数组,然后调用recursivePrint方法并传递此空数组。 要记住的事情: 仍然留下一些代码来打印最后一个元素(Current array size(which is ONE) - 1 = 0),该元素将在此递归方法调用完成后执行
  6. 再次检查数组是否为空,因为现在为空,只需返回控制语句即可。
    1. 现在,控件返回执行先前步骤中剩余的代码,即 连续在第4点打印元素10
    2. 因为控制语句到达方法的结尾,所以它返回以打印元素10,如第3点中所述。
    3. 再次到达方法的结尾,控制语句返回到main方法,并打印不包含任何内容的空字符串。

希望这对您有所了解。祝一切顺利。一旦理解,使用它会很有趣。

答案 1 :(得分:0)

以下是您的程序执行情况的说明:

  • main方法声明一个int数组,并将对该数组的引用传递给reversePrint。这是第一次调用reversePrint,因此我们将其称为#1。
  • reversePrint(呼叫#1)收到对名为 numbers 的数组的引用,该数组包含[10,20,30,40,50]。
    • 数字。长度不为0,因此该方法继续。
    • 创建一个名为 a 的新数组,其中一个元素比 numbers 短。它填充有[20,30,40,50]。
    • 虽然仍处于reversePrint#1中,但我们引用包含[20、30、40、50]的 a 来调用reversePrint(将称为#2)。但是我们的reversePrint#1尚未完成。它正在等待呼叫2的结果。
  • reversePrint(呼叫#2)收到对名为 numbers 的数组的引用,该数组包含[20、30、40、50]。
    • 数字。长度不为0,因此该方法继续。
    • 创建一个名为 a 的新数组,其中一个元素比 numbers 短。它填充有[30,40,50]。
    • 虽然仍处于reversePrint#2中,但我们引用包含[30、40、50]的 a 来调用reversePrint(将称为#3)。但是我们的reversePrint#2尚未完成。它正在等待呼叫#3的结果。
  • reversePrint(呼叫#3)收到对名为 numbers 的数组的引用,该数组包含[30、40、50]。
    • 数字。长度不为0,因此该方法继续。
    • 创建一个名为 a 的新数组,其中一个元素比 numbers 短。它填充有[40,50]。
    • 虽然仍处于reversePrint#3中,但我们引用包含[40,50]的 a 来调用reversePrint(将称为#4)。但是我们的reversePrint#3尚未完成。它正在等待呼叫4的结果。
  • reversePrint(呼叫#4)收到对名为 numbers 的数组的引用,该数组包含[40,50]。
    • 数字。长度不为0,因此该方法继续。
    • 创建一个名为 a 的新数组,其中一个元素比 numbers 短。它填充有[50]。
    • 虽然仍处于reversePrint#4中,但我们使用包含[50]的 a 引用来调用reversePrint(将称为#5)。但是我们的reversePrint#4尚未完成。它正在等待呼叫5的结果。
  • reversePrint(呼叫#5)收到对名为 numbers 的数组的引用,该数组包含[50]。
    • 数字。长度不为0,因此该方法继续。
    • 创建一个名为 a 的新数组,其中一个元素比 numbers 短。它填充有[]。
    • 虽然仍处于reversePrint#5中,但我们调用带有包含[]的 a 的引用的reversePrint(将称为#6)。但是我们的reversePrint#5尚未完成。它正在等待呼叫#6的结果。
  • reversePrint(呼叫#6)收到对名为 numbers 的包含[]的数组的引用。
    • 数字 .length为0,因此该方法返回到调用方#5。
  • reversePrint#5完成,打印出其数组的第一个元素50。
  • reversePrint#4完成,打印出其数组的第一个元素40。
  • reversePrint#3完成,打印出其数组的第一个元素30。
  • reversePrint#2完成,打印出其数组的第一个元素20。
  • reversePrint#1完成,打印出其数组的第一个元素10。
  • 主体完成,打印出空白行。