简体   繁体   English

为什么递归在不同的递归调用位置上有不同的作用

[英]Why does recursion act differently for different placements of recursive call

I'm trying to understand how recursion works. 我试图了解递归的工作原理。 I have two codes that have different outputs due to the placement of the recursive call. 由于递归调用的位置,我有两个具有不同输出的代码。 I understand that it's SUPPOSED to have different outputs, but I don't understand WHY the output is what it is. 我知道应该有不同的输出,但是我不明白为什么输出是它的原样。

Code 1 (recursive call placed AFTER print): 代码1(在打印后进行递归调用):

public class Test {
    public static void main(String[] args) {
        xMethod(5);
    }

    public static void xMethod(int n) {
        if (n > 0) {
            System.out.print(n + " ");
            xMethod(n - 1);
        }
    }
}

The above output is 5 4 3 2 1. I understand why I get this output. 上面的输出是5 4 3 2 1.我理解为什么得到这个输出。 It's because first, 5 is printed, then 5 is deducted by 1 and 4 is printed, and so on. 这是因为首先打印5,然后将5减去1,再打印4,依此类推。

What is I don't understand is the output of the following code, when the recursive call is place before the print. 当递归调用位于打印之前时,我不理解的是以下代码的输出。

Code 2 (recursive call placed before print): 代码2(在打印之前进行递归调用):

public class Test {
    public static void main(String[] args) {
        xMethod(5);
    }

    public static void xMethod(int n) {
        if (n > 0) {
            xMethod(n - 1);
            System.out.print(n + " ");
        }
    }
}

The above output is 1 2 3 4 5. I can't figure out why I get this output. 上面的输出是1 2 3 45。我不知道为什么得到此输出。 I would imagine the output to be 4 3 2 1, as the 5 is deducted, then printed as 4, and so on. 我可以想象输出是4 3 2 1,减去5,然后打印为4,依此类推。 But this obviously is not the case. 但这显然不是事实。

Can someone help me understand what is going on in the recursive process? 有人可以帮助我了解递归过程中发生了什么吗?

In first case printing is done and then call happens. 在第一种情况下,打印完成,然后发生呼叫。

In second case calls happens in this way : 在第二种情况下,呼叫是以这种方式发生的:

x(5) -> x(4) -> x(3) -> x(2) -> x(1) -> print(1) ->print(2) ->print(3) ->print(4) -> print(5)

Printing starts from the end call. 从结束通话开始打印。

x(5)
  |
  x(4)                            print(5)
    |                             | 
    x(3)                    print(4)
      |                     |
      x(2)            print(3)
        |             |
        x(1)    print(2)
          |     | 
          print(1)  

In case of first 如果是第一个

  print(5)
  x(5)
  |
  print(4)
  x(4)                            
    |
    print(3)                             
    x(3)                    
      |
      print(2)                     
      x(2)            
        | 
        print(1)  
        x(1)    

In the second code the line: System.out.print(n + " "); 在第二个代码行中: System.out.print(n + " "); will not be executed unless all the recursive calls get completed. 除非所有递归调用都完成,否则将不会执行。

The recursive function is calling itself before executing the print line. 递归函数在执行打印行之前会自行调用。

In the first script, 在第一个脚本中

public static void xMethod(int n) {
    if (n > 0) {
        System.out.print(n + " ");
        xMethod(n - 1);
    }
}

The output is printed before the step into the recursive call. 在进入递归调用之前,将打印输出。

In the second script, 在第二个脚本中,

public static void xMethod(int n) {
    if (n > 0) {
        xMethod(n - 1);
        System.out.print(n + " ");
    }
}

The function keeps stepping "into" the recursion ie once xMethod(n-1) is called, the line below it is not executed ie the print statement. 该函数将继续“进入”递归,即一旦调用xMethod(n-1),将不执行其下面的行,即print语句。 And this keeps happening until the last recursive call has been executed ie when x == 1, then the call goes backward and starts all the print statements beginning with the print statement for x == 1, then the print statement for x == 2 etc until the last print statement for the first call. 并且一直持续到执行完最后一个递归调用为止,即,当x == 1时,该调用向后退并开始所有打印语句,以x == 1的print语句开头,然后是x == 2的print语句直到第一个调用的最后一个打印语句。

I have listed a stack trace of your second snippet's execution flow (Wish I could have aligned the table and 4 columns better) 我已经列出了第二个片段的执行流程的堆栈跟踪记录(希望我可以将表和4列更好地对齐)

If you step through your program when debugging it, you will obtain to a similar stack trace that tells you the value of the variables as you step through the program's execution flow, tabulated similar to the info listed below: 如果在调试程序时逐步执行程序,则将获得类似的堆栈跟踪,该跟踪将在逐步执行程序的执行流程时告诉您变量的值,其列表类似于以下信息:

Stack trace| 堆栈跟踪| Value of Variable n | 变量n的值| Statement executed | 语句执行| Output 输出量

main
    xmethod(5)          5               xmethod(4)
     xmethod(4)         4               xmethod(3)
      xmethod(3)        3               xmethod(2)
       xmethod(2)       2               xmethod(1)
        xmethod(1)      1               xmethod(0)
         xmethod(0)     0               
        xmethod(1)      1            System.out.print(1 + " ")                1
       xmethod(2)       2            System.out.print(2 + " ")                1 2
      xmethod(3)        3            System.out.print(3 + " ")                1 2 3
     xmethod(4)         4            System.out.print(4 + " ")                1 2 3 4
    xmethod(5)          5            System.out.print(5 + " ")                1 2 3 4 5

You should go through this tutorial( http://www.vogella.com/articles/EclipseDebugging/article.html ) to get the hang of debugging. 您应该通读本教程( http://www.vogella.com/articles/EclipseDebugging/article.html )以掌握调试的窍门。 Debugging a program will help you to get a head-start to resolve queries like this one, yourself. 调试程序将帮助您自己亲自解决此类查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Java转发引用在不同情况下的行为是否有所不同? - Does java forward referencing act differently in different situations? 即使在递归调用之后也不会发生递归 - Recursion does not take place even after recursive call 为什么Font在不同的jres上加载不同? - Why does Font load differently on different jres? 在 Android 11 中,为什么返回按钮和向后滑动手势在我的代码中表现不同? - With Android 11, why does the back button and the back swipe gesture act differently with my code? 为什么我的 java 方法在多次运行时表现不同? - Why does my java method act differently when made to run multiple times? 为什么javax.xml.xpath.XPath对克隆节点的行为不同? - Why does javax.xml.xpath.XPath act differently with a cloned node? 为什么递归调用打印“ 123456”而不是“ 1”? - Why does the recursive call print '123456' instead of '1'? 为什么此方法会导致无限递归调用? - Why does this method cause an Infinite Recursive call? 为什么 ZF7B44CFFAFD5C52223D5498196C8A2E7BZ 上的“关闭”调用在 C# 和 Java 中表现不同? - Why does the “Close” call on a stream behave differently in C# and in Java? 为什么我的文本规范化在不同环境中的行为会有所不同? - Why does my text normalization behave differently in different environments?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM