【发布时间】:2013-11-13 00:01:58
【问题描述】:
简介
我正在构建一个 HTML5 Web 应用程序,它根据给定的数字列表创建二叉搜索树的可视化表示。
目前,我有一个算法,它根据树的最大深度(以 0 为底的值)计算每行节点之间的视觉间距:
offset = 50
offset *= pow(2, maxDepth - currentDepth)
从这里开始,节点的位置是使用这个偏移量和它的父节点的 x 位置来确定的。
该算法运行良好,因为它始终能够适应任何深度的最宽树。但是,这有时也会使树变得不必要地宽。
示例
向左分支的树(太宽):
Tree branching to the left http://f.cl.ly/items/0c0t0L0L0o411h092G2w/left.png
向两侧分枝(左右两侧可以更靠近)。
Tree branching to both sides http://f.cl.ly/items/0r3X1j0w3r1D3v1V1V3b/left-right.png
理想情况下,上面的树应该是一个金字塔形,宽度较小,边是直的,如下图所示:
平衡树(算法效果最好的情况):
Balanced tree http://f.cl.ly/items/203m2j2i3P1F2r2T3X02/balanced.png
实施
属性
我正在使用 Backbone.js 从 Node 模型创建节点。每个节点都有以下属性:
- parent(父节点)
- left(左子节点)
- right(右子节点)
- x(节点的 x 位置,以像素为单位)
- y(节点的 y 位置,以像素为单位)
上面的 x 和 y 属性是根据节点分支的方向计算得出的:
if (parent.get('left') === node) {
x = parentX - offsetX;
y = parentY + offsetY;
} else if (parent.get('right') === node) {
x = parentX + offsetX;
y = parentY + offsetY;
}
此时,x 和 y 属性是用于定位节点的确切值(每个都在容器元素中绝对定位)。
方法
- getDepth()(返回节点的base-0深度)
- getMaxDepth()(返回树中最后一行的深度)
- getRow(n)(返回深度为 n 的所有节点的数组)
问题
因此,我的问题很简单:
最小化二叉树美学宽度的最佳算法是什么?
【问题讨论】:
-
你的树到底长什么样,平衡吗?也许你应该举个例子
-
好主意;我现在添加了一些示例。
-
您应该检查每个级别有多少个节点并获得最大值,以便您可以选择图形的宽度。然后使用自下而上的方法来放置节点。如果您可以发布您的数据结构(最好是 JSON),我们可以使用特定的 js 代码而不是抽象算法来回答。
-
在您的第三个示例(具有五个节点的示例)中,如果不是从根节点开始的两个节点的两个长分支,那么理想的布局是什么?
-
好的,我已经添加了有关我的数据结构的更多细节,以及理想场景的图片。
标签: javascript algorithm binary-tree spacing graph-visualization