假设我有data BSearch x y = None | Node x y (BSearch x y) (BSearch x y)
(这意味着树是空的,或者它不是),我正在尝试编写函数bstSize :: BSearch x y -> Int
。
它基本上就像,
> bstSize None
0
> bstSize (Node 0 57 Empty (Node 0 65 Empty Empty))
2
我知道如何定义一个节点和一个节点有2个节点的树,但是我很难弄清楚如何将模式实现为第n个节点的实际代码。我唯一能想到的是计算正确括号的数量,计算次数"节点"发生在参数中,或计算次数"清空"在参数减1中发生,我不确定如何做任何这些事情。我知道我可能不得不使用递归,但我不确定我会怎么做。以下是我到目前为止的情况:
data BSearch q w = None | Node q w (BSearch q w) (BSearch q w)
bstSize :: BSearch q w -> Int
bstSize Empty = 0
bstSize(Node a b None None) = 1
bstSize(Node a b None (Node a b None None))) = 2
bstSize(Node a b None (Node a b None (Node a b None None))))) = 3
显然,我不应该完全定义2,3,4等等,但我这样做是为了看看模式是什么样的,看看我能用什么。到目前为止,我真的不明白该怎么做。
答案 0 :(得分:4)
您需要使用递归:
Data BSearch q w = None | Node q w (BSearch q w) (BSearch q w)
bstSize :: BSearch q w -> Int
bstSize None = 0
bstSize(Node _ _ la lb) = 1 + bstSize la + bstSize lb
Empty
对None
犯了一个小错误。
此外,Node
的大小是一个加上左孩子和右孩子的大小。您可以使用递归执行此操作。使用递归,您可以在不同的输入上调用相同的方法(在本例中为节点的子节点)。
因为每棵树都是空的。最终所有的孩子都会结束。
这是如何运作的?
假设您有值Node a b None (Node a b None (Node a b None None))))
,然后是函数调用
bstSize (Node a b None (Node a b None (Node a b None None))))) --1st call
将la
与None
统一lb
,(Node a b None (Node a b None None)))
统一bstSize la
。现在该函数调用bstSize lb
和la
。由于None
为0
,因此第一次调用将返回bstSize Node a b None (Node a b None None)))) --2nd call
。对于第二次调用,它更复杂。
第二个电话是:
la
现在,在此函数调用中,None
与lb
统一,因此结果为零,Node a b None None
与bstSize (Node a b None None) --3rd call
统一。这导致第三个电话:
la
由于lb
和None
都与0
统一,因此其结果均为bstSize (Node a b None None) --3rd call
= 1 + bstSize None + bstSize None
= 1+0+0
= 1
,因此结果为:
bstSize Node a b None (Node a b None None)))) --2nd call
= 1 + bstSize None + bstSize (Node a b None None))))
= 1 + 0 + 1
= 2
结果返回第二个电话:
bstSize (Node a b None (Node a b None (Node a b None None))) --1st call
= 1 + bstSize None + bstSize (Node a b None (Node a b None None))
= 1 + 0 + 2
= 3
最终结果是:
{{1}}
递归是一个强大的概念,但很容易导致无限循环。您最好确保始终使用与给定元素不同的元素进行递归调用,并且调用树是有限的。
答案 1 :(得分:2)
这是在最近的GHC中作弊的方式。不要在课堂作业上尝试这个。
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
module MyModuleNotYours
import qualified Data.Foldable as F
data BSearch x y = None
| Node x y (BSearch x y) (BSearch x y)
deriving (F.Foldable, Functor)
bstSize :: BSearch x y -> Int
bstSize = F.sum . (1 <$)