Haskell: 二叉樹和Catalan數

Haskell: 二叉樹和Catalan數

理論

Catalan數:C(2n, n)=(2n)!/n!/n!

關於n個節點二叉樹種類數和Catalan數的關係,可閱讀這篇博客

Haskell實現:二叉樹的定義

data Tree = Leaf | Node Tree Tree deriving Show
-- 這裏的leaf不是代表葉子節點,而是代表根本沒有
-- 這裏的node不需要預先定義,而只是一個名字;這個名字本身沒有任何意義,出現在模式匹配裏面才存在意義。
-- 如果結點需要包含信息,也是用模式匹配的方式追加在裏面。比如:
-- data Tree = Leaf | Node Int Tree Tree deriving Show -- 注意裏面的int

以上定義了“結點不需要包含任何信息”的二叉樹。

Haskell實現:打印二叉樹的信息

爲剛剛定義的二叉樹數據結構定義一個打印其信息的函數:

-- brace的幾種定義方式

-- 1.空的分支用沒有表示,非空的分支用括號括起來

brace :: Tree -> String
brace Leaf = ""
-- brace Leaf = "*" -- 空的分支用*表示
brace (Node lTree rTree) = "(" ++ brace lTree ++ "," ++ brace rTree ++ ")" 

-- 2.左括號跟左子樹,右括號跟右子樹
--   這種定義方式對應的實際情景:n對括號,合理的括號嵌套有多少種情形,這個問題的答案也是Catalan數。

brace :: Tree -> String
brace Leaf = ""
brace (Node lTree rTree) = "(" ++ brace lTree ++ ")" ++ brace rTree 

樹的打印方式千變萬化,根據需要的視覺效果自己把握。

Haskell實現:Catalan數的求解

求解“包含n個節點的二叉樹的種類數”:使用分治法求解,f(n) = f(n-1)f(0) + f(n-2)f(1) + f(n-3)f(2) + ... + f(1)f(n-2) + f(n-1)f(0)

trees :: Int -> [Tree] -- 返回所有不重複的包含n個結點的二叉樹的列表
trees 0 = [Leaf]
trees n = [Node lTree rTree | l <- [0 .. n-1], lTree <- trees l, rTree <- trees (n-1-l)]

列表長度即爲所求:執行length $ trees n

執行map brace $ trees n,返回一個列表,展示所有的樹的表示。

參考:魔力Haskell

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章