一棵普通树的完美树和完整树。 (哈斯克尔)

时间:2018-08-12 14:54:32

标签: haskell binary-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)


isComplete :: BTree a -> Bool
isComplete Nil = True
isComplete (Node x Nil Nil) = True
isComplete (Node _ lt Nil ) = False
isComplete (Node x Nil rt ) = False
isComplete (Node _ (Node _ Nil Nil) Nil) = True
isComplete (Node x lt  rt ) = (&&) (isComplete lt) (isComplete rt)

现在我必须为通用树实现数据类型

data GTree a = Leaf a | Branch a [GTree a] deriving (Show)

我如何检查这棵树是完整的还是完美的,我是否必须更改定义?

预先感谢

1 个答案:

答案 0 :(得分:1)

首先,让我们坚持使用二叉树。考虑下面的二叉树:

  1
 / \
2   3
   / \
  4   5

它可以表示为:

badTree = Node 1 (Node 2 Nil Nil) (Node 3 (Node 4 Nil Nil) (Node 5 Nil Nil))

这棵树既不完美也不完整,但是您的函数说它是:

> isPerfect badTree
True
> isComplete badTree
True
> 

因此,看来您仍有很多工作要做。

第二,要将其概括为“常规树”,是的,您将需要修改定义。考虑所有树处于同一级别(不要求每个节点的子代数)或所有叶子位于每个内部相同级别的常规树的子集是合理的节点具有相同数量的子代(例如2个,3个或4个),或者至少有两个或多个子代。但是,我不知道“完美的”或“完整的”常规树的公认定义,因此您会不断完善它。

第三,可能值得指出的是,您的GTree实现可能不是理想的。通常,“叶”是没有子节点的节点,但是您可以通过两种方式表示没有子节点:

Leaf 10
Branch 10 []

这些应该是同一棵树吗?如果是这样,理想情况下不应有两种不同的表示形式。