【发布时间】:2015-01-26 21:32:20
【问题描述】:
几年前,在 C# 课程中,我学会了编写二叉树,看起来或多或少像这样:
data Tree a = Branch a (Tree a) (Tree a) | Leaf
我看到了它的好处,它在分支上有它的值,这允许快速轻松地查找和插入值,因为它会在每个分支的根上遇到一个值,直到它遇到一个叶,没有任何价值。
然而,自从我开始学习 Haskell 以来;我见过很多这样定义的树的例子:
data Tree a = Branch (Tree a) (Tree a) | Leaf a
这个定义让我很困惑。我看不出在 不 分支的元素上有数据的用处,因为它最终会导致一棵看起来像这样的树:
在我看来,这似乎是一个设计不佳的列表替代品。这也让我质疑它的查找时间,因为它无法评估要向下查找哪个分支以找到它正在寻找的值;而是需要遍历每个节点才能找到它要查找的内容。
那么,谁能解释一下为什么第二个版本(叶子的价值)在 Haskell 中比第一个版本更普遍?
【问题讨论】:
-
确定你可以在 C# 中做到这一点,而且也相当容易;如果你知道怎么做
-
它们只是两种不同的数据结构,可能有不同的用途、优点、缺点(也可能没有)。例如,
Data.IntMap是后一种形式(仅叶子上的数据),Data.Map是前一种形式。两者兼得有什么意义?文档中有这样的说法:“[IntMap] 在联合和交集等二元运算上表现得特别好。但是,我的基准测试表明,与 [Data.Map] 相比,它在插入和删除方面也(快得多)”。最后,我不会说第二个版本“更流行”。
标签: haskell tree binary-tree