我想编写一个Haskell函数来检查树是否是完美的树。我知道,如果树的所有叶子处于相同的深度,那么树就是完美的。
我知道我会像这样开始
perfectTree :: Tree a -> Bool
但是看到我对实际定义的掌握并不太强大,任何人都可以真正解释一个完美的树是什么以及如何在Haskell中检查树是完美的
我应该包括我定义的数据类型如下:
data Tree a = Leaf | Node a (Tree a) (Tree a)
答案 0 :(得分:7)
一种方法是定义一个辅助函数perfectTreeHeight :: Tree a -> Maybe Int
,如果它是完美的,则返回Just
树的高度,否则返回Nothing
。这更容易实现,因为您实际上从递归调用中获得了高度,因此您可以比较它们。 (提示:使用do-notation)
perfectTree
只是这个函数的一个微不足道的包装器。
import Data.Maybe (isJust)
perfectTree :: Tree a -> Bool
perfectTree = isJust . perfectTreeHeight
perfectTreeHeight :: Tree a -> Maybe Int
perfectTreeHeight = ...
答案 1 :(得分:4)
你是否试图以递归的方式思考这个问题?
解决方案:树的子树必须 all 是完美树木。此外,这些子树的深度应该相等。 <强>结束。强>
我希望这个高水平的解决方案/想法有所帮助。我避免给出perfectTree
的实际定义,因为我缺少Tree
的实际定义。
答案 2 :(得分:1)
我假设你的树看起来像这样......
data Tree a = Leaf a | Branch (Tree a) (Tree a) deriving Show
现在,我们可以沿着以下几行定义递归height
函数:
height :: Tree a -> Maybe Int
height (Leaf _) = Just 1
height (Branch a b) = ???
在第二种情况(???)中,我们想要在子树的高度上添加一个,但前提是它们是完美的,并且只有它们具有相同的高度。让我们定义一个辅助函数same
,它取出子树的高度,并返回一个包含它们高度的Maybe Int,但前提是它们都是完美的并且具有相同的高度。
same :: Eq a => Maybe a -> Maybe a -> Maybe a
same (Just a) (Just b) = if a == b then Just a else Nothing
same _ _ = Nothing
现在我们可以完成height
功能了。它需要做的就是在子树的高度加1。
height :: Tree a -> Maybe Int
height (Leaf _) = Just 1
height (Branch a b) = maybe Nothing (Just . (1+)) subTreeHeight
where subTreeHeight = same (height a) (height b)
以下是如何使用它。
main :: IO ()
main = do
let aTree = (Leaf 'a')
print aTree
print $ height aTree
let bTree = Branch (Leaf 'a') (Leaf 'b')
print bTree
print $ height bTree
let cTree = Branch (Leaf 'a') (Branch (Leaf 'b') (Leaf 'c'))
print cTree
print $ height cTree
let dTree = Branch (Branch (Leaf 'a') (Leaf 'b')) (Branch (Leaf 'c') (Leaf 'd'))
print dTree
print $ height dTree
当我跑步时,我得到:
Leaf 'a'
Just 1
Branch (Leaf 'a') (Leaf 'b')
Just 2
Branch (Leaf 'a') (Branch (Leaf 'b') (Leaf 'c'))
Nothing
Branch (Branch (Leaf 'a') (Leaf 'b')) (Branch (Leaf 'c') (Leaf 'd'))
Just 3