[英]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.