2013-02-11 194 views
2

如果你有一個二叉樹,你如何使用尾遞歸迭代(按順序使用)?我知道尾遞歸涉及到迭代時計算新值,然後當您到達基本情況時,您只需返回累積。但是當你必須調用兩次函數調用時,你如何爲樹做這件事?如何做二叉樹的尾遞歸?

+0

任何遞歸函數可以使用CPS轉換成尾遞歸。 [這個問題](http://stackoverflow.com/questions/9323036/tail-recursive-function-to-find-depth-of-a-tree-in-ocaml)顯示瞭如何在OCAML中做尾巴二叉樹處理遞歸。 – Barmar 2013-02-11 04:21:35

+1

@Barmar有趣的是,我經常聽到「我們可以使用CPS實現尾遞歸」。對於正確的尾遞歸的Scheme定義實際上並不是這樣,它指定無界尾遞歸不應該使用無界的內存。如果CPS描述了真正的尾遞歸過程,那確實適用;否則,你的延續鏈將是無限的長度。 – 2016-07-08 14:43:05

回答

6

假設深度優先從左到右遍歷,您不能對左手分支使用尾遞歸,但可以將其用於右分支。

實施例方案的代碼(假設你tree有三個存取器函數,valueleft,和right):

(define (collect-in-order tree) 
    (define (collect node result) 
    (if node 
     (collect (right node) 
       (cons (value node) 
         (collect (left node) result))) 
     result)) 
    (reverse (collect tree '()))) 

(collect (right node) ...)是在尾部位置,所以這是一個尾調用。

你也可以做一個從右到左遍歷,在這種情況下,它的左側下坡是尾遞歸:

(define (collect-in-order tree) 
    (let collect ((node tree) 
       (result '())) 
    (if node 
     (collect (left node) 
       (cons (value node) 
         (collect (right node) result))) 
     result))) 
+0

這是'爲了散步'嗎? – omega 2013-02-11 04:07:49

+0

當然,使用這種策略可以實現按順序的遍歷。 – 2013-02-11 04:08:38

+0

那怎麼辦呢? – omega 2013-02-11 04:09:48