[英]Creating all Bool binary trees of size n
我正在嘗試創建大小為n的所有二叉樹,但是想不出辦法。
樹是這樣定義的
> data Tree :: * -> * where
> Tip :: a -> Tree a
> Bin :: Tree a -> Tree a -> Tree a
> deriving (Eq,Show)
一棵樹的大小是指它具有的“技巧”和“箱”的數量。
我需要創建一個獲取Int n
並返回該大小的所有樹的列表的函數。
> getTrees :: Int -> [Tree Bool]
例如對於getTrees 1
我應該得到[Tip True, Tip False]
因為這是所有可能的大小為1的樹。
我想不出一種方法來生成所有大小為n的樹。
讓我們先從簡單的樹開始:一號樹:
> getTrees :: Int -> [Tree Bool]
> genTrees 1 = [Tip True, Tip False]
現在,我們必須考慮更大的Int
。 那么2
呢? 事實證明,如果Bin
和Tip
增加大小,則不存在任何大小為2的樹。 任何Bin
導致1 + k + j
的額外大小,其中k
和j
必須是有效的樹大小。 可以看到,這只會生成奇數大小的樹。
因此,我們可以在繼續之前丟棄所有無效的Int
:
> genTrees n | even n || n <= 0 = []
> genTrees n =
現在我們知道我們的n
是奇數,至少是3。 因此,我們確實必須將Bin
用作其他樹的根。 其他樹木? 好吧,還記得上面的公式嗎? 我們需要生成兩個新的樹,它們的大小分別為j
和k
,使得1 + j + k = n
。 幸運的是,我們有一個生成這些樹的函數,稱為genTrees
。 我們可以將所有內容合並到一個列表中:
> [Bin l r | i <- [1,3..n-1], l <- genTrees i, r <- genTrees (n - 1 - i)]
Tip
視為大小。 現在有效的樹大小是多少? Tip
有助於大小(畢竟,只有它們具有有效負載)。 好的,我想有些不喜歡我嘗試導致解決方案的方式,因此無需進一步說明:這是一個 :
getTrees :: Int -> [Tree Bool]
getTrees 1 = [Tip True, Tip False]
getTrees n = do
leftSize <- [0..n-2]
let rightSize = (n-1) - leftSize
left <- getTrees leftSize
right <- getTrees rightSize
return $ Bin left right
您可以在此處看到偶數大小的樹會遇到問題,因為這些樹有時會到達getTrees 0
,這將把leftSize <- [0..(-2)]
拉到leftSize <- [0..(-2)]
並以一個空列表結束
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.