我试图用haskell写一棵红黑树,在红黑树的属性中有一个注解,所有不包含数据的叶子都是黑色的。
我想写这样的东西:
data EmptyNode = EmptyNode{
data = ???,
color = ???, <-- it should black (assume that it is False)
left = ???,
right = ???
}
data NodeBR a = NodeBR {
data :: a,
color :: Bool,
left :: NodeBR,
right :: NodeBR
}
data TreeBR a = EmptyNode | NodeBR a (TreeBR a) (TreeBR a)
我不明白两件事,什么类型适合我在通常的语言中替换Null(我理解你不能在这里使用undefined)并使用构造函数,我如何在EmptyNode中指定颜色默认为False?
1条答案
按热度按时间ecbunoof1#
一种解决方案是以更“Haskell”的方式来定义红黑树(简称RBT),因此有两种可能的方式来构造RBT:
Leaf
(代码中的EmptyNode
)Node a c l r
(代码中为NodeBR
),其中a
是数据,c
是颜色,l
和r
也是RBT。在上面的代码行中,我们定义了带有两个构造函数的数据类型
RBT a
:Leaf :: RBT a
Node :: a -> Bool -> RBT a -> RBT a -> RBT a
个这意味着:
Leaf
的类型为RBT a
Node
是一个函数,取a
、Bool
(颜色)、RBT a
(左树)、RBT a
(右树),返回一个RBT a
。因此,在这种情况下,我们不需要为
Leaf
指定NULL,因为根本不需要这样说(即,对于Leaf,我们想要说没有数据,没有左/右子树)。要将
Leaf
视为黑色,我们可以## Heading ##使用模式匹配在RBT a
上定义一个函数:您在代码中提到的record syntax只是生成
color
函数的语法糖,但在这种情况下,使用记录语法无法生成Leaf情况下的正确代码,因为它们在声明中不相同。因此,当您必须检查
RBT a
是否为Leaf
时,您可以只使用模式匹配,而不用使用其他语言中的“if-with-null”。更新:
正如amalloy在注解中提到的,为了更好的可读性,我们可以将颜色定义为一个单独的数据类型:
请注意,
Bool
和Color
是 * 同构的 *。