您能否告诉我上面的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