Haskell玫瑰树size函数计数逻辑存疑,求解析误区
Haskell玫瑰树size函数的问题分析
首先明确玫瑰树的定义:
data Rose a = MkRose a [Rose a]
你找到的解决方案存在一个笔误:函数名应为size而非roseSize,修正后的正确代码是:
size (MkRose _ []) = 1 size (MkRose a (t:ts)) = size t + size (MkRose a ts)
你的分析误区:重复计数根节点
我们用3节点的玫瑰树做具体推导,帮你定位问题:
假设你构造的3节点树是「根节点带一个子节点,子节点再带一个子节点」,即:
tree3 = MkRose 1 [MkRose 2 [MkRose 3 []]]
按照修正后的size函数计算:
- 计算
size tree3,匹配第二个模式:size tree3 = size (MkRose 2 [MkRose 3 []]) + size (MkRose 1 []) - 计算
size (MkRose 2 [MkRose 3 []]),匹配第二个模式:size (MkRose 2 [MkRose 3 []]) = size (MkRose 3 []) + size (MkRose 2 []) size (MkRose 3 [])和size (MkRose 2 [])都匹配第一个模式,结果各为1,所以这一步总和是1+1=2。size (MkRose 1 [])结果为1,最终总和是2+1=3,和实际节点数一致。
如果你得到了4,大概率是错误地在每一步额外加了1来统计当前根节点。比如错误推导会写成:
size tree3 = 1 + size (MkRose 2 [MkRose 3 []]) + size (MkRose 1 [])
这样就会得到1+2+1=4,但函数的第二个模式逻辑是把树拆成「第一个子树」和「原根节点+剩余子树」两部分,这两部分的size之和已经包含了所有节点,不需要额外加当前根节点的1。
再验证另一种3节点树(根节点带两个子节点)
如果树是MkRose 1 [MkRose 2 [], MkRose 3 []],计算过程:
size (MkRose 1 [MkRose 2 [], MkRose 3 []]) = size (MkRose 2 []) + size (MkRose 1 [MkRose 3 []]) = 1 + (size (MkRose 3 []) + size (MkRose 1 [])) = 1 + (1+1) = 3
结果同样正确。
内容的提问来源于stack exchange,提问作者Jord van Eldik
相关产品推荐
相关产品推荐

