我的树定义是
data Tree = Leaf Integer | Node Tree Tree
这是一棵二叉树,只有叶子的值。 我给出了平衡树的以下定义:
如果每个节点的左右子树中的叶子数最多相差一个,我们就说树是平衡的,叶子本身很平衡。
我尝试按如下方式创建一个平衡树:
t :: Tree
t = Node (Node (Node (Leaf 1) (Leaf 2)) (Node(Leaf 3)(Leaf 4))) (Node (Node (Leaf 5) (Leaf 6)) (Node (Leaf 7) (Leaf 8)) )
如果上面是一棵仅在树叶上有价值的平衡树,你可以告诉我吗?
另一个问题是,如何创建另一个仅在叶子上具有值的树,并且根据上述定义它是不平衡的。
由于
答案 0 :(得分:4)
如果
t
上方的data CountedTree = CLeaf Integer | CNode Integer Tree Tree
是一棵仅在树叶处有价值的平衡树,能告诉我吗?
我可以,但我不会。但是,我希望我能指导您完成编写一个确定给定树是否平衡的函数的过程。
以下肯定不是最常用的高效方法(请参见底部的相关提示),但这是一种非常模块化的方式。它也是函数式编程(尤其是惰性函数式编程)所鼓励的“通过转换计算”方法的一个很好的例子。我似乎很清楚,要问的第一个问题是“每个节点有多少叶子下降?”我们无法直接在树中写下答案,但我们可以创建一个有答案的新树:
CountedTree
CountedTree
的每个节点都有一个整数字段,表示有多少叶子从中下降。
您应该能够编写一个函数来读取Leaf
中的叶子总数,无论是Node
还是getSize :: CountedTree -> Integer
:
CountedTree
下一步是确定countedBalanced :: CountedTree -> Bool
countedBalanced CLeaf = ?
countedBalanced (CNode _ left right)
= ?? && ?? && getSize left == getSize right
是否平衡。这是一个骨架:
Tree
我离开了最后一步:将CountedTree
转换为countTree :: Tree -> CountedTree
:
balanced :: Tree -> Bool
balanced t = ?? (?? t)
最后你可以把它全部包装起来:
-- The balance status of a tree. Either it's
-- unbalanced, or it's balanced and we store
-- its total number of leaves.
data Balance = Unbalanced | Balanced Integer
getBalance :: Tree -> Balance
现在事实证明,你实际上并不需要复制和注释树来确定它是否平衡。你可以直接做得更多。这是一种更加高效的方法,但更少模块化方法。我会给你相关的类型,你可以填写这个功能。
{{1}}