Haskell 2-3-4 树

Posted

技术标签:

【中文标题】Haskell 2-3-4 树【英文标题】:Haskell 2-3-4 Tree 【发布时间】:2012-01-22 20:36:39 【问题描述】:

我们被要求在 Haskell 中创建一个 2-3-4 树,如写入数据类型、插入函数和显示函数。

我发现很难获得有关这种树的信息,即使使用我熟悉的语言(Java、C++)也是如此。

到目前为止我所拥有的 -

data Tree t = Empty 
    | Two t (Tree t)(Tree t) 
    | Three t t (Tree t)(Tree t)(Tree t) 
    | Four t t t (Tree t)(Tree t)(Tree t)(Tree t) deriving (Eq, Ord, Show)


leaf2 a = Two a Empty Empty
leaf3 a b = Three a b Empty Empty Empty
leaf4 a b c = Four a b c Empty Empty Empty Empty

addNode::(Ord t) => t ->  Tree t -> Tree t
addNode t Empty = leaf2 t
addNode x (Two t left right)
    | x < t = Two t (addNode x left) right
    | otherwise = Two t left (addNode x right)

这可以编译,但我不确定它是否正确,但不确定如何开始将插入写入三节点或四节点。

作业还说,显示功能的“导出显示”是不够的,它应该以通常在图表中看到的格式打印出树。再次,不确定如何去做。

任何帮助或指导表示赞赏。

【问题讨论】:

您是否阅读了有关 2-3-4 树的***文章?你了解它对插入算法的描述吗?如果是这样,你能描述一下你在 Haskell 中尝试实现它的确切位置吗?如果没有,请说明您不明白的部分。 哦,关于 Show 实例:你知道如何在 Haskell 中定义实例吗?你知道你的树的显示功能应该是什么样子吗?您在尝试实施时遇到了什么问题? 另外,请查看the drawTree function in the standard Data.Tree module,并考虑如何使其适应您的类型。 我承认,***的文章看起来确实很混乱。文章中链接的参考资料之一可能会让您的运气更好。 此时我遇到的主要问题是插入到 4 节点。由于我无法返回树,因此我需要提前检查下一个节点是否为 4 节点,以便保留数据以拆分节点。 【参考方案1】:

我对 2-3-4 树一无所知,但对于三节点,您可以从以下内容开始:

addNode t (Three x y left mid right)
  | cond1 = expr1
  | cond2 = expr2
  (etc)

cond1cond2expr1expr2 究竟是什么,取决于 2-3-4 树的定义。

至于show 方法,大致是这样的:

instance (Show t) => Show (Tree t) where
  show Empty = ...
  show (Two x l r) = ...show x...show l...show r...
  show (Three x y l m r) = ...
  show (Four x y z l m n r) = ...

实现取决于您希望它的外观,但对于非空情况,您可能会在显示的树的所有组件上调用show。如果你想缩进树的嵌套部分,那么也许你应该创建一个单独的方法:

instance (Show t) => Show (Tree t) where
  show = showTree 0

showTree :: Show t => Int -> Tree t -> String
showTree n = indent . go
  where indent = (replicate n ' ' ++)
        go Empty = "Empty"
        go (Two x l r) = (...show x...showTree (n+1) l...showTree (n+1) r...)
        (etc)

【讨论】:

【参考方案2】:

我们被要求创建一棵 2-3-4 树

我的哀悼。我自己曾经不得不为家庭作业实施一个。 2-3-4 树是具有 B-tree 的所有缺点而没有任何优点的 B-tree,因为像您那样为每个孩子的数量分别编写案例就像只有 2 个的列表一样麻烦-4 个元素。

要点:B-tree 插入算法应该可以工作,只是固定大小。科门等人。在他们的书中有一个伪代码Introduction to algorithms(严重的命令性警告!)。

使用数据元素和子元素列表而不是四格代数数据类型可能会更好,即使该类型不会强制节点的大小。至少它会更容易扩展节点大小。

【讨论】:

以上是关于Haskell 2-3-4 树的主要内容,如果未能解决你的问题,请参考以下文章

是否有可能在haskell中有一套理解?

在 Haskell 中不变异树

如何在 Haskell 中表示两棵树之间的映射?

在 Haskell 中交错列表列表

在 Haskell 中合并两个列表

如何在 Haskell 中实现 B+ 树?