我在使用 tikz 绘制这种类型的树时遇到了问题,以及如何在 tikz 中为一个节点写两条线标签
答案1
正如 @Jubobs 所说,通常不太可能让别人从头开始制作你的图片,但我碰巧没有更好的事情可做。所以你看:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes,calc,decorations.markings}
\tikzset{bigtip/.style={-,decoration={markings,mark=at position 1 with {\arrow[line width=3pt]{stealth}}},postaction={decorate}}}
\begin{document}
\begin{tikzpicture}
% Bottom level
\node[circle,draw] (20) at (0,0) {20};
\node[circle,draw] (21) at (2,0) {21};
\node[circle,draw] (24) at (4,0) {24};
\node[circle,draw] (28) at (6,0) {28};
\node[circle,draw] (30) at (8,0) {30};
\node[circle,draw] (38) at (10,0) {38};
% Middle levels
\node[ellipse,draw] (20-21) at (1,1.5) {[20-21]};
\node[ellipse,draw] (28-30) at (7,1.5) {[28-30]};
\node[ellipse,draw] (20-24) at (3,3) {[20-24]};
\node[ellipse,draw] (28-38) at (9,3) {[28-38]};
% Top level
\node[ellipse,draw] (20-38) at ($($(20-24.center)!.5!(28-38.center)$)+(90:1.5)$) {[20-38]};
% Arrows
\foreach \x\y in {20/20-21,21/20-21,28/28-30,30/28-30,20-21/20-24,24/20-24,28-30/28-38,38/28-38,20-24/20-38,28-38/20-38}{
\draw[bigtip] (\x)--(\y);
}
% Labels - bottom level
\node[anchor=north] at ($(20)+(270:.4)$) {\begin{tabular}{l}20,20,1\\lb,ub,freq\end{tabular}};
\node[anchor=north] at ($(21)+(270:.4)$) {\begin{tabular}{l}21,21,2\\lb,ub,freq\end{tabular}};
\node[anchor=north] at ($(24)+(270:.4)$) {\begin{tabular}{l}24,24,2\\lb,ub,freq\end{tabular}};
\node[anchor=north] at ($(28)+(270:.4)$) {\begin{tabular}{l}28,28,1\\lb,ub,freq\end{tabular}};
\node[anchor=north] at ($(30)+(270:.4)$) {\begin{tabular}{l}30,30,1\\lb,ub,freq\end{tabular}};
\node[anchor=north] at ($(38)+(270:.4)$) {\begin{tabular}{l}38,38,3\\lb,ub,freq\end{tabular}};
% Labels - middle levels
\node[anchor=east] at ($(20-21)+(180:.7)$) {\begin{tabular}{l}lb,ub,freq\\20,21,3\end{tabular}};
\node[anchor=east] at ($(28-30)+(180:.7)$) {\begin{tabular}{l}lb,ub,freq\\28,30,2\end{tabular}};
\node[anchor=east] at ($(20-24)+(180:.7)$) {\begin{tabular}{c}lb,ub,freq\\20,24,5\end{tabular}};
\node[anchor=west] at ($(28-38)+(0:.7)$) {\begin{tabular}{c}lb,ub,freq\\28,38,5\end{tabular}};
% Labels - top level
\node[anchor=west] at ($(20-38)+(0:.7)$) {\begin{tabular}{c}lb,ub,freq\\20,38,10\end{tabular}};
\end{tikzpicture}
\end{document}
结果:
需要注意以下几点:
我调整了节点的间距,使其(在某种程度上)更加均匀
箭头指向每个节点的中心,而不是底部。要使它们指向底部,请将其替换
\draw[bigtip] (\x)--(\y);
为\draw[bigtip] (\x)--(\y.south);
。可以手动调整箭头尖的大小,通过在代码顶部的命令中更改
\arrow[line width=3pt]
为(例如)\arrow[line width=2pt]
使其变小。\tikzset
我不确定您是否希望节点旁边的所有文本都左对齐,但我将大部分文本左对齐,并将其中一些文本居中,就像您所做的那样。在标签部分中,将 in
l
使其\begin{tabular}{l}
与左侧对齐,将 将 更改l
为 ac
使其居中。我不确定如何获得某些部分的红色和绿色脊状下划线。我觉得我好像在某个地方见过它,但那已经是很久以前的事了。
答案2
仅供参考,这棵树是用强大的forest
包。特别注意开头的树的结构化定义及其提供的优势(代码经济就是其中之一):
\documentclass{article}
\usepackage{forest}
\usetikzlibrary{shapes}
\newcommand\Mylabelt[1]{%
\begin{tabular}{c}
#1 \\
lb, ub, freq
\end{tabular}%
}
\newcommand\Mylabelb[1]{%
\begin{tabular}{c}
lb, ub, freq \\
#1
\end{tabular}%
}
\begin{document}
\begin{forest}
where n children=0
{tier=word,shape=circle}
{shape=ellipse,before typesetting nodes={content=[#1]}
},
for tree={
s sep=1.5cm,
draw,
edge={<-,>=latex},
}
[20-38,name=ro,
[20-24,name=l
[20-21,name=ll
[20,name=lll]
[21,name=llr]
]
[24,name=lr
]
]
[28-38,name=r
[28-30,name=rl
[28,name=rll]
[30,name=rlr]
]
[38,name=rr
]
]
]
\foreach \Nombre/\Valores in {l/{20,24,5},ll/{20,21,3},rl/{28,30,2}}
\node[anchor=east] at (\Nombre.west) {\Mylabelt{\Valores}};
\foreach \Nombre/\Valores in {ro/{28,30,10},r/{20,38,5}}
\node[anchor=west] at (\Nombre.east) {\Mylabelt{\Valores}};
\foreach \Nombre/\Valores in
{lll/{20,20,1},llr/{21,21,2},lr/{24,24,1},%
rll/{28,28,1},rlr/{30,30,1},rr/{38,38,3}%
}
\node[anchor=north] at (\Nombre.south) {\Mylabelt{\Valores}};
\end{forest}
\end{document}