如何在二叉树的侧面打印出这样的输出呢?在
__/a
__/ \b
\ _/c
\_/ \d
\e
(欢迎使用更漂亮的ascii艺术)
以下是一些不太管用的代码:
^{pr2}$其输出如下:
_/hg19
_/ \rheMac2
_/ \mm9
/\_/bosTau4
/ \_/canFam2
_/ \pteVam1
\_/loxAfr3
\dasNov2
Scope crawe:如果您可以传入一个函数,该函数将返回要打印的任何节点的字符串;这样,我有时也可以打印有关非离开节点的信息。因此,节点是否有要打印的内容由作为参数传入的函数控制。在
以下是JSON中的一些测试数据:
{
"left": {
"left": {
"left": {
"left": {
"name": "hg19",
"sequence": 0
},
"right": {
"name": "rheMac2",
"sequence": 1
}
},
"right": {
"name": "mm9",
"sequence": 2
}
},
"right": {
"left": {
"name": "bosTau4",
"sequence": 3
},
"right": {
"left": {
"name": "canFam2",
"sequence": 4
},
"right": {
"name": "pteVam1",
"sequence": 5
}
}
}
},
"right": {
"left": {
"name": "loxAfr3",
"sequence": 6
},
"right": {
"name": "dasNov2",
"sequence": 7
}
}
}
您需要递归地处理这个问题,并跟踪各个子树的大小。尤其是根在哪里。非平衡树很容易看起来像这样:
现在假设您已经构建了这个树,在添加父级时,您需要将它转换为以下内容。在
^{2}$关键是从树叶开始。它们是微不足道的。然后定义一种聚合两个子树的方法,假设它们具有不同的行数和子树根节点的不同位置。在
下面是一些代码,它们实现了别处描述的通用递归方法。树的内部表示是子节点的字符串(叶)或元组(对)。节点中间“片段”的内部表示是元组}是根上下的行数,
(above, below, lines)
,其中above
和{lines
是每个部分行上的迭代器(左边没有空格)。在下面是一些输出示例:
^{2}$还有一个更不对称的例子,也许可以说明为什么我在行尾之前不在左边填充空格(via
flatten
)。如果下半身被垫在左边,上臂的一些部分会穿过填充区域。在这是一个“显而易见”的递归算法——魔鬼在细节中。没有“u”是最容易写的,这使得逻辑稍微复杂一些。在
也许唯一的“洞察力”是
gap_above = l_above
-也就是说右“臂”的长度与左子树右侧的长度相同(你需要读几遍)。它使事情相对平衡。请参阅上面的不对称示例。在更详细地理解事情的一个好方法是修改},并为每个调用指定一个不同的字符。然后你就可以确切地看到哪个逻辑生成了哪个空间。这是使用A.B、C和D从上到下、从上到下调用pad时得到的结果(显然,当空间量为零时没有字符):
pad
例程,使其接受一个字符而不是{这里有更多的解释here(尽管这棵树略有不同)。在
制作一个表示结构,包括一个字符串数组和一个“花瓣”的行号。在
rep(leaf)为[0,repr(叶值)]
rep(非叶),给定
top = nonleaf.left
和bottom = nonleaf.right
:每行rep(顶部)垫空格,如果上面的花瓣,或斜线在适当的位置,如果下面。类似地,在rep(底部)的每一行都填充空格(如果在底部的花瓣之下),或者在上面的适当位置用反斜杠填充。repr(nonleaf)则是[顶部的高度,顶部的填充线,然后是底部的填充线]。在
示例:
注意,在上面的情况下,填充的宽度是花瓣下面的行数;在底部情况下,填充的宽度对应于petal。因此,在(abcde)的情况下,顶部有2行,花瓣1,所以填充是(2-1==1)一个字符;底部有花瓣2,所以填充是2个字符。在
如果您愿意,您还可以在第(petal-1)行的每个非叶处添加一个“u”(在所有其他行上添加一个额外的空格)。在
显然,这些都不是代码(“\”是一个等待发生的语法错误),但从这里实现应该不会太困难。在
相关问题 更多 >
编程相关推荐