2012-07-21 109 views
2

這是一個顯示尾遞歸的好例子嗎?java中的尾遞歸

public printName(){ 
    System.out.println("Smith"); 
    printName(); 
} 

我不打算在現實生活中這樣做,但我把這作爲我的考試的一個例子。這是正確的嗎?

+12

這是一個更好的例子來顯示堆棧溢出:) – dasblinkenlight 2012-07-21 13:57:41

+0

是的,但這將導致無限遞歸(並在堆棧空間用完時崩潰程序)。 – nhahtdh 2012-07-21 13:57:41

+0

@dasblinkenlight有時我會回來查看您的評論。它永遠不會讓我振作起來。 – kritzikratzi 2014-02-04 20:42:24

回答

15

否,原因有二:

  • 尾遞歸是唯一有價值的,當編譯器支持它(尾調用優化)。在Java中,它仍然以StackOverflowError

  • 結束,這將很好地顯示一些停止條件。你的代碼相當於永遠循環運行。

考慮斯卡拉幾乎相同的代碼,唯一的區別是,Scala編譯器執行尾調用優化和循環將永遠運行下去:

def printName() { 
    println("Smith"); 
    printName() 
} 
+4

我不知道:尾遞歸只是尾遞歸。編譯器可以對其進行優化,但它不是重點。如我錯了請糾正我。 – nhahtdh 2012-07-21 13:59:21

+0

@nhahtdh:OP不問這是否是尾遞歸(無疑在那)。他問是否這是一個**遞歸尾巴的好例子**。恕我直言,它不是。 – 2012-07-21 14:02:51

+0

根據[Wikipedia](http://en.wikipedia.org/wiki/Tail_call)和我自己的CS記憶,語言是否特別處理尾遞歸併不重要 - 該示例是尾遞歸。 – 2012-07-21 14:03:41

1

我會說這是尾的一個例子遞歸,因爲你在程序尾部遞歸:)但是我不認爲JVM會優化這個,這可能是你想要的。

12

尾遞歸的更好的例子是這樣的:

public printName(int level){ 
    if(level <= 0) 
     return; 
    System.out.prntln("Smith"); 
    printName(--level); 
} 

此例子包括其中遞歸被終止的重要組成部分。

除此之外:由於其他答案已經提到:由於Java沒有優化尾遞歸,所以在這種語言中使用它沒有意義。所以你基本上最終會自己優化你的算法 - 通過迭代。這就是尾遞歸的一點:可以證明,任何尾遞歸算法都可以轉化爲迭代算法。