簡體   English   中英

為什么遞歸在不同的遞歸調用位置上有不同的作用

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

我試圖了解遞歸的工作原理。 由於遞歸調用的位置,我有兩個具有不同輸出的代碼。 我知道應該有不同的輸出,但是我不明白為什么輸出是它的原樣。

代碼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);
        }
    }
}

上面的輸出是5 4 3 2 1.我理解為什么得到這個輸出。 這是因為首先打印5,然后將5減去1,再打印4,依此類推。

當遞歸調用位於打印之前時,我不理解的是以下代碼的輸出。

代碼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 + " ");
        }
    }
}

上面的輸出是1 2 3 45。我不知道為什么得到此輸出。 我可以想象輸出是4 3 2 1,減去5,然后打印為4,依此類推。 但這顯然不是事實。

有人可以幫助我了解遞歸過程中發生了什么嗎?

在第一種情況下,打印完成,然后發生呼叫。

在第二種情況下,呼叫是以這種方式發生的:

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

從結束通話開始打印。

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

如果是第一個

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

在第二個代碼行中: System.out.print(n + " "); 除非所有遞歸調用都完成,否則將不會執行。

遞歸函數在執行打印行之前會自行調用。

在第一個腳本中

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

在進入遞歸調用之前,將打印輸出。

在第二個腳本中,

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

該函數將繼續“進入”遞歸,即一旦調用xMethod(n-1),將不執行其下面的行,即print語句。 並且一直持續到執行完最后一個遞歸調用為止,即,當x == 1時,該調用向后退並開始所有打印語句,以x == 1的print語句開頭,然后是x == 2的print語句直到第一個調用的最后一個打印語句。

我已經列出了第二個片段的執行流程的堆棧跟蹤記錄(希望我可以將表和4列更好地對齊)

如果在調試程序時逐步執行程序,則將獲得類似的堆棧跟蹤,該跟蹤將在逐步執行程序的執行流程時告訴您變量的值,其列表類似於以下信息:

堆棧跟蹤| 變量n的值| 語句執行| 輸出量

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

您應該通讀本教程( http://www.vogella.com/articles/EclipseDebugging/article.html )以掌握調試的竅門。 調試程序將幫助您自己親自解決此類查詢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM