How to check if my binary search Tree is complete? (Haskell)

人盡茶涼 提交于 2019-12-13 03:15:36

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!