答案1
该解决方案使用实验包,正义树, 基于森林。更具体地说,它使用版本 0.5。如果您希望使用它,请询问。我在这里确实使用问题来测试它,但我可以为那些鲁莽的人提供代码。(旧版本在这里某处,但不足以用于此示例。)
一个关键优势森林是在源中指定树的简洁性。正义树是包装器森林旨在支持对树的左侧和右侧进行轻松注释。
环境justtree
需要一个强制参数。该参数可以为空。否则,它指定树的序言,并可用于自定义内容和格式。
\begin{justtree}
{
<preamble, if required>
}
<tree specification in forest's bracket notation>
\end{justtree}
基本介绍森林并使用括号符号指定树的说明在第二部分中提供我对一般的树绘制问题的回答。
在这种情况下,树的实际规格如下:
[, annotate
[
[
[[]]
]
[
[[]]
]
[
[[]]
]
]
[
[
[[]]
]
[
[[]]
]
[
[[]]
]
]
[, annotate
[
[[]]
]
[
[[]]
]
[, annotate
[[, annotate]]
]
]
]
树的序言完成了大部分工作。
将注释向右移动,为箭头腾出空间:
just format={xshift=1.5em},
annotate
为应该具有注释和箭头的级别创建一个样式:
annotate/.style={% style should be applied to the rightmost node at each level for which an arrow and annotation is required
if level=1{% first level of tree (apparent root - the real root is added automatically at level 0)
right just=$cn^2$,
}{
if n children=0{% terminal nodes
right just=$\Theta(n^{\log_43})$
}{% other nodes (if annotated)
right just/.wrap pgfmath arg={$(\frac{3}{16})^##1cn^##1$}{level()},
},
},
tikz+/.wrap pgfmath arg={\draw [->] (.east) -- (right just ##1.west);}{level()},
},
对于终端节点,我们改变节点和其父节点的级别距离,对节点使用虚线边,对父节点不使用边:
where n children=0{
!u.no edge,
!u.l sep-=10pt,
l sep-=5pt,
edge={dotted},
}{},
使树内所有节点的内容使用数学模式:
for tree={
math content,
指定树中节点的内容,并在左侧绘制箭头、在底部绘制花括号:
delay={
if level=1{
content=cn^2,
tikz+={
\draw [<->] (!F.south west) +(-2.5em,0) coordinate (c) -- (.north -| c) node [midway, fill=white] {$\log_4n$};
\draw [decorate, decoration={brace, mirror}] (!F.south west) -- (!L.south east) node [midway, below] {$n^{\log_43}$};
},
}{
if n children=0{% terminal nodes have different content
content=T(1),
delay={% their parents have no content - delay this so it overwrites the specification below
!u.content=,
}
}{% non-terminal nodes
if level=0{}{% which are not at level 0 (the real root, automatically added by the justtree style)
content/.wrap pgfmath arg={c(\frac{n}{#1})^2}{int(4^(level("!u")))},
}
}
}
},
},
}
结果justtrees.sty
如下:
代码:
\documentclass[tikz,border=10pt]{standalone}
\usepackage{justtrees}% version 0.5
\usetikzlibrary{decorations.pathreplacing}
\begin{document}
\begin{justtree}
{
just format={xshift=1.5em},
annotate/.style={% style should be applied to the rightmost node at each level for which an arrow and annotation is required
if level=1{
right just=$cn^2$,
}{
if n children=0{
right just=$\Theta(n^{\log_43})$
}{
right just/.wrap pgfmath arg={$(\frac{3}{16})^##1cn^##1$}{level()},
},
},
tikz+/.wrap pgfmath arg={\draw [->] (.east) -- (right just ##1.west);}{level()},
},
where n children=0{
!u.no edge,
!u.l sep-=10pt,
l sep-=5pt,
edge={dotted},
}{},
for tree={
math content,
delay={
if level=1{
content=cn^2,
tikz+={
\draw [<->] (!F.south west) +(-2.5em,0) coordinate (c) -- (.north -| c) node [midway, fill=white] {$\log_4n$};
\draw [decorate, decoration={brace, mirror}] (!F.south west) -- (!L.south east) node [midway, below] {$n^{\log_43}$};
},
}{
if n children=0{
content=T(1),
delay={
!u.content=,
}
}{
if level=0{}{
content/.wrap pgfmath arg={c(\frac{n}{#1})^2}{int(4^(level("!u")))},
}
}
}
},
},
}
[, annotate
[
[
[[]]
]
[
[[]]
]
[
[[]]
]
]
[
[
[[]]
]
[
[[]]
]
[
[[]]
]
]
[, annotate
[
[[]]
]
[
[[]]
]
[, annotate
[[, annotate]]
]
]
]
\end{justtree}
\end{document}