Reingold-Tilford算法的步骤是什么?如何编程?

时间:2012-10-29 20:01:29

标签: c# winforms algorithm user-interface tree

从第3页的演示文稿:Graphs and Trees,可以直观地了解Reigngold-Tilford过程中发生的事情;它还提前对这个算法进行了模糊的总结:"...starts with bottom-up pass of the tree; [finishes with] Top-down pass for assignment of final positions..."我可以通过递归方式实现两个方向传递,我知道Y值与每个节点的生成级别相对应,但我是仍然失去了如何解决X坐标。

我确实遇到过这个项目:A Graph Tree Drawing Control for WPF但是有很多代码我很难找到应该是一个简单的2-3方法来定义X值。 (也没有WPF的经验)

我几天来一直在寻找并尝试如何做到这一点,所以非常感谢您的帮助!

2 个答案:

答案 0 :(得分:21)

我发现jwpat7's answer中列出的文章非常有用,虽然我花了一些时间才弄清楚这个算法所需的确切逻辑,所以我写了own blog post来简化解释。

以下是确定X节点位置的明文逻辑:

  • 从树的post-order traversal开始

  • 如果每个节点是一个集合中的第一个,则为每个节点分配一个初始X值,如果不是,则为previousSibling + 1

    enter image description here

  • 如果某个节点有子节点,请找到所需的X值,使其居中于子节点上。

    • 如果节点是最左侧的节点,请将其X设置为该值

    • 如果节点不是最左边的节点,请将节点上的Mod属性设置为(X - centeredX),以便移动所有子节点,使它们在此节点下居中。树的最后一次遍历将使用此Mod属性来确定每个节点的最终X值。

  • 确定此节点的任何子节点是否与此节点左侧的兄弟节点子节点重叠。基本上对于每个Y,从两个节点获取最大和最小的X,并进行比较。

    • 如果发生任何碰撞,请将节点移动一段时间。移动子树只需要添加节点的XMod属性。

    • 如果节点被移动,也会在两个重叠的子树之间移动任何节点,使它们等间隔

  • 检查以确保在计算最终X时,没有负X值。如果找到任何内容,请将最大的一个添加到根节点的XMod站点以将整个树移到

  • 使用预先遍历遍历对树进行第二次遍历,并将节点父节点中每个Mod值的总和添加到{{1} X属性

上面树的最终X值如下所示:

enter image description here

我在my blog post中有一些更多的细节和一些示例代码,但是在这里包含所有内容的时间太长了,我想专注于算法的逻辑而不是代码细节。

答案 1 :(得分:2)

有一些文章包括代码,在billmill.org的python中和1991年2月1日的page 2中的C Dr. Dobb's Journal article。你已经要求“简单的2-3种方法”(也许意味着食谱方法),但在它们的一般性中很好地绘制树是NP完全问题(参见Supowit,KJ和EM Reingold,“很好地绘制树木的复杂性”,Acta Informatica 18,4,1983年1月,377-392,DDJ文章中的参考文献4)。 Reingold-Tilford方法在线性时间内或多或少地绘制二叉树,而Buchheim的变化在线性时间内或多或少地绘制了n-ary树。然而,billmill的文章指出(在说明原则6之后不久),“到目前为止我们已经在本文中查看了一个简单的算法,我们发现它不够......”因此更简单的方法工作的可能性好的很小。