如何检查我的二进制搜索树是否完成? (哈斯克尔)

时间:2018-08-11 14:17:07

标签: haskell binary-search-tree

data BTree a = Nil | Node a (BTree a) (BTree a) deriving Show

我了解了两个二进制搜索树。一个是完美的,另一个是 完成。

二叉树是完美二叉树,其中所有内部节点都有两个孩子,所有叶子都在同一级别。

如果所有级别都已完全填充,则二叉树就是完整的二叉树,除了最后一个级别,并且最后一个级别中的所有键都尽可能保留

检查二叉树是否完美的代码非常简单

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)

如何检查树是否完整?

2 个答案:

答案 0 :(得分:1)

我相信您正在尝试使这个问题稍微简单一些。要检查二叉树是否完美,您不仅需要知道两个孩子都是完美的,而且要知道它们具有相同的深度。因此,递归地知道isPerfect对孩子的结果仍然不足以回答问题。

在编写递归函数时会遇到很多问题。您需要编写一个递归函数来做一些比您想做的要强大的事,然后从中提取想要的信息。您可以从这里开始,例如:

-- | 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

(这也不是理想的实现。当您已经知道深度是错误的时,您可能会在b方面做大量工作来验证完美性。但这是可行的,我选择了简单性来代替效率。)

现在您的递归为您提供了正确的信息,您应该可以以此编写isPerfectisComplete将使用类似的策略。

答案 1 :(得分:-1)

您只需要添加一种情况:

isPerfect (Node _ lt Nil ) = False

isComplete中仍然有效,但前提是lt没有子代。

isComplete (Node _ (Node _ Nil Nil) Nil) = True