簡體   English   中英

將遞歸轉換為尾遞歸

[英]converting recursion to tail recursion

我正在閱讀將遞歸算法轉換為迭代算法的內容。 我遇到了一個博客文章http://blog.moertel.com/posts/2013-05-11-recursive-to-iterative.html,解釋了將遞歸算法首先轉換為尾遞歸算法,然后再將尾遞歸轉換為迭代的。 在帖子中,解釋了當我們要將遞歸算法轉換為尾遞歸算法時,我們應該首先了解return of the recursive callreturn statement of the calling function.return statement of the calling function.之間發生了什么return statement of the calling function. 完成此操作后,我們應嘗試向遞歸函數添加秘密要素/累加器參數,然后確定要返回的內容。 我已經按照博客文章中給出的示例的概念進行操作,但是我無法解決博客結尾處給出的練習。 我無法決定我的累加器參數應該是什么? 我應該如何基於該累加器參數來做出決策。 我不想要解決方案,但有一些關於如何解決該問題的建議。 這是練習代碼:

def find_val_or_next_smallest(bst, x):
    """Get the greatest value <= x in a binary search tree.

    Returns None if no such value can be found.

"""
    if bst is None:
        return None
    elif bst.val == x:
        return x
    elif bst.val > x:
        return find_val_or_next_smallest(bst.left, x)
    else:
        right_best = find_val_or_next_smallest(bst.right, x)
        if right_best is None:
            return bst.val
        return right_best 

提前致謝!

我張貼此內容以替換昨天的評論並顯示代碼。

在遞歸算法中,每個調用都會創建一個堆棧框架,其中包含函數的局部變量和傳遞的參數。 所有堆棧幀一起保存某種狀態信息。 當您要避免遞歸時,將沒有其他堆棧框架。 因此,必須在非遞歸函數中維護數據的重要部分。

現在到代碼。 我試圖嚴格按照說明進行操作。

這是原始來源。 我只是省略了文檔字符串,並用if s替換了return后立即出現的elif (只是首選樣式的問題)。

def find_val_or_next_smallest1(bst, x):
    if bst is None:
        return None
    if bst.val == x:
        return x
    if bst.val > x:
        return find_val_or_next_smallest1(bst.left, x)
    else:
        right_best = find_val_or_next_smallest1(bst.right, x)
        if right_best is None:
            return bst.val
        return right_best

現在到尾遞歸。 有四個分支。 兩種非遞歸,一種已經是尾遞歸,第四種需要重寫:

    right_best = find_val_or_next_smallest1(bst.right, x)
    if right_best is None:
        return bst.val
    return right_best

該分支選擇bst.val或調用結果作為結果,以較優者為准。 該調用必須最后完成,因此必須直接將bst.val傳遞給它。 該函數將獲得一個新參數,其含義是“如果找不到更好的參數,請返回此參數”。 更改之前為“如果找不到任何內容,則不返回任何內容”。 因此,我們只需要替換None值即可。 我稱這個新參數為found ,因為它是到目前為止我們發現的。

def find_val_or_next_smallest2(bst, x, found=None):
    if bst is None:
        return found
    if bst.val == x:
        return x
    if bst.val > x:
        return find_val_or_next_smallest2(bst.left, x, found)
    else:
        return find_val_or_next_smallest2(bst.right, x, found=bst.val)

博客中的直接轉換:

def find_val_or_next_smallest3(bst, x, found=None):
    while True:
        if bst is None:
            return found
        if bst.val == x:
            return x
        if bst.val > x:
            bst, x, found =  bst.left, x, found
        else:
            bst, x, found =  bst.right, x, bst.val

和清理:

def find_val_or_next_smallest4(bst, x):
    found=None
    while True:
        if bst is None:
            return found
        if bst.val == x:
            return x
        if bst.val > x:
            bst = bst.left
        else:
            bst, found = bst.right, bst.val

暫無
暫無

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

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