簡體   English   中英

了解二叉樹上的遞歸

[英]Understanding Recursion on Binary Trees

您好,我是編程的新手,所以在學校我們正在學習遞歸和二叉樹。 但是對我而言,遞歸確實使我的頭腦融化了。

所以我嘗試在二叉樹上嘗試遞歸函數以嘗試輸出預排序格式

def preorder(self, preorder_list):
    """ (BinaryTree) -> list
    Return a list of the items in this tree using a *preorder* traversal.
    """

    if self.root is not EmptyValue:
        if self.left and self.right != None:
            preorder_list.append(self.left.preorder(preorder_list))
            preorder_list.append(self.right.preorder(preorder_list))

def helper_preorder(self):
    preorder_list = []
    self.preorder(preorder_list)

    return preorder_list

當我運行此代碼時,我得到的輸出是:

例如;

[None, None, None, None]

現在,我懷疑這與我的遞歸推理有關。 因此,我想知道遞歸推理的問題所在,以及如何更好地進行遞歸。

謝謝你的時間。

您的問題是您永遠不會從preorder返回任何東西,而Python隱式地返回None 因此,您將函數的返回值附加到列表中,但該值是None 您的函數應如下所示(在偽代碼中,無效的Python) 1

preorder(node, list):
    if node is Empty:
        return list
    else:
        new_list.append(node.data)
        preorder(node.left, new_list);
        preorder(node.right, new_list);
        return list

請注意,我正在復制return語句,因此可以對其進行優化,但是我將其設置為這種方式,因為如果將其視為基本案例或遞歸調用,則最容易理解遞歸。

要理解遞歸2 ,請考慮將難題分解為更小,更容易的問題。 我將舉一個簡單的示例,這是經典的遞歸示例之一: factorial(n)

什么是factorial(n) 這是一個很難回答的問題,所以讓我們找到更簡單的方法。

從數學課上,我們知道n! = n*(n-1)*(n-2)*...*(2)*(1) n! = n*(n-1)*(n-2)*...*(2)*(1) ,所以從這里開始。 我們可以立即看到n! = n * (n-1)! n! = n * (n-1)! 有幫助; 現在我們可以編寫階乘函數的啟動器:

factorial(n):
    return n * factorial(n-1)

但是還沒有完成。 如果我們運行它,它將永遠存在並且不會停止3 因此,我們需要一個基本案例:遞歸的停止點,現在問題變得如此簡單以至於我們知道了答案。

幸運的是,我們有一個自然的基本案例: 1! = 1 1! = 1 ,根據定義是正確的。 因此,我們將其添加到函數中:

factorial(n):
    if n == 1: return 1
    else return n * factorial(n)

為了弄清楚它是如何工作的,讓我們跟蹤一些小的東西,比如說n=4

因此,我們稱之為factorial(4) 顯然4 != 1 ,所以factorial(4) = 4*factorial(3) 現在,我們重復此過程,這是遞歸的妙處:將相同的算法應用於原始問題的較小子集,然后從這些部分構建解決方案。

我們的蹤跡看起來像這樣:

factorial(4) = 4*factorial(3)
factorial(4) = 4*3*factorial(2)
factorial(4) = 4*3*2*factorial(1)

現在,我們知道factorial(1)是:它只是基本情況1。 所以最后我們有了

factorial(4) = 4*3*2*1
factorial(4) = 24

1這只是一種可能的方式; 還有其他人,但這是我當場想出的
2您必須先了解遞歸(對不起,我無法抗拒)
3在現實世界中,它最終將停止:因為每個遞歸調用都使用一些內存(以跟蹤函數參數和局部變量等),所以無限遞歸的代碼最終將超過為其分配的內存,並且將崩潰。 這是堆棧溢出錯誤的最常見原因之一

暫無
暫無

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

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