簡體   English   中英

創建所有大小為n的Bool二叉樹

[英]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呢? 事實證明,如果BinTip增加大小,則不存在任何大小為2的樹。 任何Bin導致1 + k + j的額外大小,其中kj必須是有效的樹大小。 可以看到,這只會生成奇數大小的樹。

因此,我們可以在繼續之前丟棄所有無效的Int

> genTrees n | even n || n <= 0 = []
> genTrees n =

現在我們知道我們的n是奇數,至少是3。 因此,我們確實必須將Bin用作其他樹的根。 其他樹木? 好吧,還記得上面的公式嗎? 我們需要生成兩個新的樹,它們的大小分別為jk ,使得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.

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