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

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