計算二叉樹的個數

2021-08-22 05:52:07 字數 1428 閱讀 6196

給定二叉樹的節點個數來計算能夠構成多少種不同的二叉樹。

採用的是遞迴的思想來解決這類問題。

1、因為採用遞迴的思想,我們的結束條件就是當節點個數為0.此時節點個數為0的情況,這時候構成的樹的情況為空樹,即二叉樹的個數是1.

2、因為是二叉樹,我們只需要分為兩邊來計算。即滿足這樣的條件,從根節點下來,能夠成左邊的情況的個數乘以右邊的個數的情況想乘,就得到此時這種情況的個數。例如:總共有3個節點,左邊分配2個(能構成的情況為2),右邊分配1個節點(能構成的情況為1),即本次分配的情況總數為2*1=2

3、實際上節點數為1的時候,構成的情況也是1,和0是一樣的,所以遞迴的條件,就是當節點數為0就結束。所以每次的結果都會遞迴到0。

**實現:

'''

計算二叉樹的個數

'''def count(n):

# root : 1

# left : k [0,n-1]

# right : n - 1 - k

if n == 0:

return 1

sum = 0

for k in range(n):

sum += count(k) * count(n-1-k)

return sum

用一張圖來表示呼叫棧的變化以及程式的執行過程。我們以n=3為例,其他的(n更大)的情況都是一樣的計算。

上圖,詳細解釋了每一步的執行過程。上述呼叫棧的過程遵從左到右、從上到下的過程。執行過程遵從,從右到做、從下到上的順序。

在上述的**中,有乙個很大的缺點,在呼叫棧中就體現得很明確,當我們第一步執行count(0)和count(2)後,發現後面還會用到這些,會被重複的在呼叫棧中執行,在時間和空間上都是很大的浪費。

解決方法,我們可以建立乙個快取機制,使得每次執行過的count()被儲存在快取中,這樣的話,當我們下次執行到ciunt()時,如果已經在快取中,就直接從快取中取(時間複雜度為o(1)),如果不存在我們才會遞迴。

其**如下:

'''

新增快取的方式來實現時間複雜度下降

'''def count_tree(n):

# root : 1

# left : k [0,n-1]

# right : n - 1 - k

sum = count_tree.cache.get(n,0)

if sum:

return sum

for k in range(n):

sum += count_tree(k) * count_tree(n-1-k)

return sum

count_tree.cache =

計算二叉樹的結點個數

include using namespace std extern int gnum 0 struct infor class test static int creattrees struct infor p,int k if 2 k creattrees q,1 creattrees q,2 ...

二叉樹計算

術語 1.節點的度 乙個節點含有的子樹的個數稱為該節點的度 2.葉節點或終端節點 度為零的節點 3.非終端節點或分支節點 度不為零的節點 4.父親節點或父節點 若乙個節點含有子節點,則這個節點稱為其子節點的父節點 5.兄弟節點 具有相同父節點的節點互稱為兄弟節點 6.節點的層次 從根開始定義起,根為...

二叉樹組合個數

hw 2020.8.19筆試第二題 題目描述 給出二叉樹上每個節點的深度,請你計算滿足條件的二叉樹共有多少種。輸入描述 第一行包含乙個整數n,表示二叉樹上節點的數量 1 n 1000 第二行包含n個整數,d1,d2,dn,表示每個節點的深度 0 di n 1 輸出描述 輸出滿足條件的二叉樹數量,因為...