这是一个非常普通的二叉树,除了其中一个节点可能是空的。
我想找到一种方法以水平方式输出它(即根节点在左侧并向右扩展)。
我有一些垂直扩展树的经验(顶部的根节点,向下扩展),但在这种情况下,我不确定从哪里开始。
最好,它将遵循以下几条规则:
例如,这是一个有效的树,有六个末端节点(节点由名称及其深度表示):编辑:请参阅问题底部的替代方法,更简单的渲染
[a0]-----------[b3]------[c5]------[d8]
\\\-----------[e9]
\\----[f5]
\-[g1]--------[h4]------[i6]
\\--------------------[j10]
\-[k3]
代表垂直的、显式的二叉树:
0个
/\
1 克 *
/\\
2 * * *
/\\
3 k * b
//\
4 小时 * *
/\\\
5 * * f c
/\/\
6 * 我 * *
//\
7 * * *
//\
8 * * d
//
9 * e
/
10 小时
(分支为了紧凑而折叠;
*
代表冗余的单子(monad)节点;请注意, *
是实际节点,每个节点存储一个子节点,为了便于展示,这里省略了名称)(另外,澄清一下,我想生成第一个水平树;而不是这个垂直树)
我说语言不可知,因为我只是在寻找一种算法;我说 ruby 是因为无论如何我最终都必须在 ruby 中实现它。
假设每个
Node
数据结构仅存储其 id、左节点和右节点。大师
Tree
class 跟踪所有节点并有足够的算法来查找:我已经知道:
任何人都知道我可以从哪里开始?我应该采用递归方法吗?迭代?
一些伪代码也会很酷,非常感谢 =)
进度
根据 walkytalky 的建议,我决定看看将每个“相关”或重要节点映射到网格会是什么样子,列是深度,行是其末端节点可识别的。这是发生的情况(跳过第 7 列,因为深度 7 中没有重要节点):
深度:0 1 2 3 4 5 6 8 9 10
A B C D
电子
F
吉我
j
克
使用广度优先或深度优先搜索来生成这个网格应该很容易。也许最简单的方法是简单地保留一个二维数组并将找到的每个重要节点放入其中,为每个“第二个 child ”插入一行。
现在,知道这些事实:
我们可以看到,给定任何有效的网格,有 一种明确的方式 “连接点”,可以这么说;有一个明确的树被表示。
现在,“连接点”不再是一个二叉树结构的问题……它只是一个装饰问题。我们只需要构建一个算法来正确放置正确的
-
的和 \
是他们可以去的地方,也许只遵循简单的网格/词典规则,而不是二叉树结构规则。基本上,这意味着渲染树的问题现在是更简单的问题 渲染网格 ,带有华丽的装饰。
任何人都可以提出任何制定这些规则的方法吗?或者可能是完全不同的方法?
编辑
我设想了一个更容易的最终渲染:
--d0----d1----d3----d4----d5----d6----d8----d9----d10-- => 引导线(未呈现)
[a0 ]-------[b3 ]-------[c5 ]-------[d8 ]
| |\--------------[e9]
|\---------[f5]
\---[g1 ]-------[h4 ]-------[i6 ]
|\---------------------------[j10]
\---[k3]
--d0----d1----d3----d4----d5----d6----d8----d9----d10-- => 引导线(未呈现)
尝试创建这个可能更容易,而不是我之前发布的那个。一方面,它保留了漂亮的网格形状,而且您不必对对角线变化无常。行都沿着清晰可见的列线映射。不幸的是,它远没有第一个那么漂亮。
最佳答案
如果有N
端节点,必须有N-1
有 2 个 child 的内部节点。 (可以有任意数量的具有 1 个子节点的内部节点,我们必须对其进行计数以获得深度,否则将忽略。)因此,生成树等效于将这些节点定位在网格上,其中:
N
1+floor(log2(N))
之间和 2*N-1
,取决于有多少重叠;尽管 那么,让我们看看:
更新:
正如你所说,定位足以明确确定连接,但你仍然需要做一些自下而上的工作才能做到这一点,所以我可能仍然会在网格构建过程中进行“标记”步骤。
我有点认为打印是微不足道的,足以掩盖,但是:
size of fixed elements + max label length + floor(log10(depth) + 1)
. (例如,固定元素可能是 [
和 ]-
。我们可以替换 ]\n
作为端点的后缀。) 如果首先生成直线版本,然后在字符数组中进行一些替换,则将其转换为打印对角线可能是最简单的——否则,您可能会遇到在与所在列不同的列中渲染长垂直分支的情况起源。
在某些时候,我可能会尝试将其放入代码中,但今天可能不会——要做的事情!
关于ruby - 以文本/ASCII 形式呈现水平二叉树的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3056968/