我知道如何使用在 TikZ 中创建多部分节点\nodepart
,并且我知道如何从这些节点部分绘制线条以将它们连接到其他节点:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\tikzset{
bnode/.style = {
draw,
rectangle split,
rectangle split horizontal,
rectangle split parts=4
}
}
\begin{document}
\begin{tikzpicture}
\node[bnode]
(root)
{ \nodepart{one}
$12$ \nodepart{two}
$15$ \nodepart{three}
$20$ \nodepart{four}
$\times$};
\draw[->]
(root.south west) -- +(-4,-1)
node[bnode, anchor=north]
(childnode)
{ \nodepart{one}
$3$ \nodepart{two}
$9$ \nodepart{three}
$10$ \nodepart{four}
$12$};
\draw[->]
(root.one split south) -- +(-2,-1)
node[bnode, anchor=north]
(childnode)
{ \nodepart{one}
$13$ \nodepart{two}
$14$ \nodepart{three}
$15$ \nodepart{four}
$\times$};
\draw[->]
(root.two split south) -- +(0,-1)
node[bnode, anchor=north]
(childnode)
{ \nodepart{one}
$17$ \nodepart{two}
$18$ \nodepart{three}
$\times$ \nodepart{four}
$\times$};
\draw[->]
(root.three split south) -- +(2,-1)
node[bnode, anchor=north]
(childnode)
{ \nodepart{one}
$21$ \nodepart{two}
$29$ \nodepart{three}
$\times$ \nodepart{four}
$\times$};
\end{tikzpicture}
\end{document}
渲染:
即使在这个简单的例子中,我也必须计算子节点的正确位置,因为它们是重叠的。想象一下在树中添加另一个级别。这些计算将变得非常繁琐。
我知道 TikZ 有一些不错的树语法,可以轻松绘制树,但我没有立即看到它在这里如何应用。有没有办法使用 TikZ 的child
语法来处理多部分节点,这样我就不必担心子节点的间距和位置。
需要澄清的是:多部分节点的每个部分都应该能够拥有它自己的适当的子节点,并且子节点本身也是多部分节点,而多部分节点又可以有多个子节点(每个节点部分一个)。
答案1
问题源于a'
比 更宽a
。因此,您可以设置text width=1.0em, align=center
以确保每个节点的宽度相同:
代码:
\documentclass[border=2pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\tikzset{
bnode/.style = {
text width=1.0em, align=center,
draw,
rectangle split,
rectangle split horizontal,
rectangle split parts=4
}
}
\begin{document}
\begin{tikzpicture}
\node[bnode]
(root)
{ \nodepart{one}
$a$ \nodepart{two}
$b$ \nodepart{three}
$c$ \nodepart{four}
$d$};
\draw (root.one south) -- +(0,-1) node[draw, anchor=north](q) {$a'$};
\draw (root.two south) -- +(0,-1) node[draw, anchor=north](q) {$b'$};
\end{tikzpicture}
\end{document}
答案2
经过近五年的时间......
使用calc
、chain
和positioning
库,节点之间的距离很容易确定。除此之外,代码也简短明了:
\documentclass[tikz, margin=3mm]{standalone}
\usetikzlibrary{arrows.meta,
calc, chains,
positioning,
shapes.multipart}
\begin{document}
\begin{tikzpicture}[
node distance = 13mm and 1mm,
start chain = A going right,
mpn/.style args = {#1/#2/#3/#4}{draw,
rectangle split, rectangle split horizontal,
rectangle split parts=4,
on chain=A,
node contents={ \nodepart{one} $#1$
\nodepart{two} $#2$
\nodepart{three} $#3$
\nodepart{four} $#4$}
},
]
\node[mpn=3/9/10/12];
\node[mpn=13/14/15/\times];
\node[mpn=17/18/\times/\times];
\node[mpn=21/29/\times/\times];
%
\node[mpn=12/15/20/\times,
above=of $(A-1.north west)!0.5!(A-4.north east)$];
\foreach \i in {1,...,4}
\draw[-Stealth, semithick, shorten >=1mm, shorten <=1mm]
(A-5) -- (A-\i.north);
\end{tikzpicture}
\end{document}
这个两层树可以很容易地扩展到更多层。较低层的设计应与上面的 MWE 类似,较高层只是上面 MWE 顶层的重复。
附录:
利用该forest
包你可以按照自己的意愿设计一棵树:
\documentclass[tikz, margin=3mm]{standalone}
\usetikzlibrary{arrows.meta,
shapes.multipart}
\usepackage{forest}
\newcommand\mpnc[4]{\nodepart{one} $#1$
\nodepart{two} $#2$
\nodepart{three} $#3$
\nodepart{four} $#4$}
\begin{document}
\begin{forest}
for tree = {
rectangle split,
rectangle split horizontal,
rectangle split parts=4,
draw,
%
parent anchor=south,
child anchor=north,
edge = {-Stealth, semithick, shorten >=1mm, shorten <=1mm},
l sep=12mm,
s sep=1mm,
}
[{\mpnc{12}{15}{20}{\times}}
[{\mpnc{3}{9}{12}{\times}}]
[{\mpnc{13}{14}{15}{\times}}]
[{\mpnc{17}{18}{\times}{\times}}]
[{\mpnc{21}{29}{\times}{\times}}]
]
\end{forest}
\end{document}
答案3
不幸的是,这不是真正的答案。不过,如果时间还不算晚,我想分享我的一个解决方案。
它不是很好,可以改进,但我希望它能以某种方式帮助你。:)
编辑:\tikzstyle
取而代之\tikset
。
\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{arrows, shapes, trees, calc, positioning}
\tikzset{
key/.style = {
circle,
fill = white,
dotted,
thick,
draw,
},
vazio/.style = {
draw = none,
fill = none,
},
no/.style = {
rectangle split,
rectangle split horizontal,
rectangle split parts = #1,
rectangle split draw splits = false,
rounded corners,
fill = black!15,
draw = black!85,
thick,
anchor = center,
minimum height = 1.8em,
},
no b/.style = {
rectangle split,
rectangle split horizontal,
rectangle split parts = #1,
rectangle split empty part width = 1.3ex,
rectangle split draw splits = false,
rounded corners,
fill = black!15,
draw = black!85,
thick,
anchor = center,
minimum height = 1.8em,
},
edge from parent/.style = {
thick,
-latex,
draw = black,
},
child/.style = {
edge from parent path = {(\tikzparentnode.west)
++(0.06cm+#1*0.65cm, -0.18cm) -- (\tikzchildnode)},
},
nil/.style = {
edge from parent = {thick, -square, draw = gray},
},
}
\begin{document}
\begin{tikzpicture}[scale = 0.65, transform shape]
\tikzstyle{every node} = [no b]
\tikzstyle{level 1} = [sibling distance = 12cm]
\tikzstyle{level 2} = [sibling distance = 3cm]
\node (tree) {42}
child[child = 0] {node {19 \nodepart{two} 33}
child[child = 0] {node {10 \nodepart{two} 15 \nodepart{three} 16
\nodepart{four} 18}}
child[child = 1] {node {22 \nodepart{two} 27 \nodepart{three} 29}}
child[child = 2] {node {35 \nodepart{two} 40 \nodepart{three} 41}}
}
child[child = 1] {node {61 \nodepart{two} 74 \nodepart{three} 85
\nodepart{four} 95}
child[child = 0] {node {47 \nodepart{two} 49 \nodepart{three} 53}}
child[child = 1] {node {65 \nodepart{two} 68 \nodepart{three} 72}}
child[child = 2] {node {77 \nodepart{two} 81}}
child[child = 3] {node {88 \nodepart{two} 90 \nodepart{three} 93
\nodepart{four} 94}}
child[child = 4] {node {97 \nodepart{two} 98}}
}
;
\draw [latex-, thick] (tree) -- ++ (0, 1);
\end{tikzpicture}
\end{document}