Haskell 查看BST的大小
假设我有Haskell 查看BST的大小,haskell,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 我知道如何定义一个有1个节点的树和一个有2个节点的树,但是我很难理解如何将该模式实
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
我知道如何定义一个有1个节点的树和一个有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等的样子,但我这样做是为了看看这个模式是什么样子,看看我能用什么。到目前为止,我真的不知道该怎么做。您需要使用递归:
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
时犯了一个小错误
此外,节点的大小
是1加上左子节点和右子节点的大小。您可以使用递归来实现这一点。使用递归,可以对不同的输入调用相同的方法(在本例中是节点的子级)
因为每棵树都是空的。最终所有的孩子都会死
这是如何工作的?
假设您有值节点a b None(节点a b None(节点a b None))
,然后函数调用
bstSize (Node a b None (Node a b None (Node a b None None))))) --1st call
将la
与None
和lb
与统一(节点a b None(节点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
与节点a b 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 (Node a b None None))) --1st call
= 1 + bstSize None + bstSize (Node a b None (Node a b None None))
= 1 + 0 + 2
= 3
结果返回到第二个调用:
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 None) --3rd call
= 1 + bstSize None + bstSize None
= 1+0+0
= 1
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
递归是一个强大的概念,但很容易导致无限循环。您最好确保始终使用不同于给定元素的递归调用,并且调用树是有限的。以下是在最近的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 <$)
{-#语言派生可折叠}
{-#语言派生函子#-}
模块MyModuleNotYours
导入符合条件的数据。可折叠为F
数据b搜索x y=无
|节点x y(b搜索x y)(b搜索x y)
派生(F.可折叠,函子)
bstSize::BSearch x y->Int
bstSize=F.sum。(1看起来您需要一些递归…提示:您不需要指定树的整个骨架;当前节点的子节点也可以由变量绑定。如:bstSize(node a b l r)=……
。