查看BST的大小

时间:2015-01-24 22:55:04

标签: haskell

假设我有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等等,但我这样做是为了看看模式是什么样的,看看我能用什么。到目前为止,我真的不明白该怎么做。

2 个答案:

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

EmptyNone犯了一个小错误。

此外,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

laNone统一lb(Node a b None (Node a b None None)))统一bstSize la。现在该函数调用bstSize lbla。由于None0,因此第一次调用将返回bstSize Node a b None (Node a b None None)))) --2nd call 。对于第二次调用,它更复杂。

第二个电话是:

la

现在,在函数调用中,Nonelb统一,因此结果为零,Node a b None NonebstSize (Node a b None None) --3rd call 统一。这导致第三个电话:

la

由于lbNone都与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 <$)