【问题标题】:Drawing a binary tree structure in haskell在haskell中绘制二叉树结构
【发布时间】:2016-02-24 17:59:41
【问题描述】:

我在 Haskell 工作并试图绘制一个树数据结构,它使用具有一两个子树的“节点”和空树的“提示”。

绘制过程取最高层节点向上绘制一条直线,其长度等于节点本身的值。

提示没有为它们画线。

从这条初始线开始,节点的子节点被绘制成与父线成“d”角。对于节点的左子节点,线条向左倾斜,右子节点向右倾斜。这些行的长度分别等于每个孩子的值。

这对树结构中的每个节点重复。

我的问题是我们使用单个光标(可以向前、向后和旋转)来绘制树。 因此,绘制整棵树似乎需要某种算法来系统地绘制一棵树(例如,优先在左侧绘制孩子,直到达到尖端,然后回溯并绘制右侧孩子)

但是这种方法似乎非常复杂,因为 Haskell 无法存储变量,这些变量需要记住光标已经绘制的树的哪些部分。

有没有一种算法可以做到这一点? 如果没有,是否有其他方法可以在 2d 平面上使用单个光标绘制树?

感谢您的帮助。

【问题讨论】:

  • 听起来你想要一个 "depth-first tree traversal" 的算法,并且一种可以帮助你“记住光标已经绘制的树的哪些部分所需的变量”的技术是使用zipper
  • 如果您编写的每个绘图函数之后都会将光标移回其原始位置,则不需要保留任何状态。只需在树上递归并将其写出来。但是,如果您显示一些代码(您的绘图 API 是什么,您的数据类型是什么),会更容易提供帮助。
  • @JoachimBreitner 我不确定你的意思,你能详细说明一下吗?
  • 查看 adamse 的答案,它几乎可以确定。

标签: haskell tree drawing draw


【解决方案1】:

假设这是您的绘图 API:

forward :: Int -> IO ()
backward :: Int -> IO ()
rotate :: Double -> IO ()

根据您的描述,树数据类型如下所示:

data Tree
  = Bin Tree Int Tree
  | Tip

然后您可以按照您的建议递归地绘制左子树,然后是右子树:(树的“预序深度优先”遍历)

draw :: Double -- ^ Angle
     -> Tree
     -> IO ()
draw d Tip = return () -- no lines for Tips
draw d (Bin l v r) = do
  -- draw this node's line
  forward v

  -- draw left subtree
  rotate d
  draw d l

  -- draw right subtree
  rotate (2 * (-d))
  draw d r

  -- return to starting position
  rotate d
  backward v

【讨论】:

  • 嗯,这很有意义,感谢您的解释。
猜你喜欢
  • 2015-08-20
  • 1970-01-01
  • 1970-01-01
  • 2014-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-04
  • 1970-01-01
相关资源
最近更新 更多