问题
data BTree a = Nil | Node a (BTree a) (BTree a) deriving Show
I learned about two binary search trees. One is perfect the other one is complete.
A Binary tree is Perfect Binary Tree in which all internal nodes have two children and all leaves are at same level.
A Binary Tree is complete Binary Tree if all levels are completely filled except possibly the last level and the last level has all keys as left as possible
The code to check if a binary tree is perfect is pretty easy
isPerfect :: BTree a -> Bool
isPerfect Nil = True
isPerfect (Node x Nil Nil) = True
isPerfect (Node x lt Nil ) = False
isPerfect (Node x Nil rt ) = False
isPerfect (Node x lt rt ) = (&&) (isPerfect lt) (isPerfect rt)
How can I check if the tree is complete?
回答1:
I believe you are trying to make this problem just a little bit simpler than possible. To check whether a binary tree is perfect, you need to know not just that both children are perfect, but that they have the same depth. So knowing the result of isPerfect
recursively on the children still isn't enough to answer the question.
This comes up a lot when writing recursive functions. You need to write a recursive function to do something a little bit more powerful than you want, and then extract the info you want from that. You could start with this, for example:
-- | Gives the depth of a tree if it's perfect;
-- or otherwise, Nothing
perfectDepth :: BTree a -> Maybe Int
perfectDepth Nil = Just 0
perfectDepth (Node x a b) =
case (perfectDepth a, perfectDepth b) of
(Just da, Just db) | da == db -> Just (da + 1)
_ -> Nothing
(This isn't an ideal implementation, either. You will potentially do a bunch of work on the b
side verifying perfectness when you already knew the depth was wrong. But it works, and I chose simplicity over efficiency here.)
Now that your recursion is giving you the right information, you should be able to write isPerfect
in terms of this. isComplete
would use a similar strategy.
回答2:
You only need to add one case:
isPerfect (Node _ lt Nil ) = False
could still be valid in isComplete
, but only if lt
has no children.
isComplete (Node _ (Node _ Nil Nil) Nil) = True
来源:https://stackoverflow.com/questions/51800519/how-to-check-if-my-binary-search-tree-is-complete-haskell