你好(抱歉我的英语不好……)
我正在处理一个 Tex 文档来生成算法图:它对我来说非常好,只是我想减少叶子使用的空间(似乎树与网格一起工作并且可以重复使用一些空单元)。
以下是代码(该算法没有什么特别之处,只是展示可能的情况):
\documentclass{standalone}
\usepackage{tikz}
\usepackage{tikz-qtree}
\usetikzlibrary{shapes,arrows}
% styles
\tikzstyle{principal} = [draw,rectangle split, rectangle split horizontal=false,rectangle split parts=2,minimum height=5mm]
\tikzstyle{bloc} = [rectangle, draw, fill=blue!20, text width=5em, text centered, rounded corners, minimum height=5mm]
\tikzstyle{decision} = [diamond, draw, fill=blue!20, text width=4.5em, text badly centered, node distance=3cm, inner sep=0pt]
\tikzstyle{io} =[draw,trapezium,trapezium left angle=70,trapezium right angle=-70,minimum height=5mm]
\tikzstyle{op} = [rectangle, draw, text width=5em, text centered, minimum height=5mm]
\tikzstyle{sequence} = [draw, ellipse,fill=red!20, node distance=3cm, minimum height=5mm]
\tikzstyle{nop} = [ellipse,fill=red!5, node distance=3cm, minimum height=5mm]
% document
\begin{document}
\begin{tikzpicture}[level distance=3cm,
sibling distance=2mm, thick,scale=0.9,
every node/.style={scale=0.9, font=\large}]
\Tree
[.\node[principal] {\nodepart{one}\shortstack{Principal}\nodepart{two}\shortstack{entier i,j\\reel j}};
[.\node[sequence] {POUR} ;
[.\node[decision]{\textsf{chaque i de 1 a 4 pas 1}};]
[.\node[sequence] {\textsf{repeter}};
[.\node [io] {\textsf{j $\leftarrow$ LIRE()}}; ]
]
]
[.\node[op] {\textsf{i $\leftarrow 1$}};]
[.\node [sequence] {TQ} ;
[.\node [decision] {\textsf{($i <= 4$)}};]
[.\node [sequence] {\textsf{repeter}};
[.\node [io] {\textsf{ECRIRE i}}; ]
]
]
[.\node[sequence] {SI} ;
[.\node[decision] {\textsf{($i <= 10$)}};]
[.\node[sequence] {\textsf{si vrai}};
[.\node[op] {\textsf{j $\leftarrow 10$}};]
[.\node[op] {\textsf{j $\leftarrow 10$}};]
[.\node[op] {\textsf{j $\leftarrow 10$}};]
]
[.\node[sequence] {\textsf{si faux}};
[.\node[op] {\textsf{j $\leftarrow 12$}};]
[.\node[op] {\textsf{j $\leftarrow 12$}};]
[.\node[op] {\textsf{j $\leftarrow 12$}};]
[.\node[sequence] {SI} ;
[.\node[decision] {\textsf{($i <= 10$)}};]
[.\node[sequence] {\textsf{si vrai}};
[.\node[op] {\textsf{j $\leftarrow 10$}};]
]
[.\node[sequence] {\textsf{si faux}};
[.\node[op] {\textsf{j $\leftarrow 12$}};]
]
]
]
]
]
\end{tikzpicture}
\end{document}
节点放置可以更近一些以节省空间。是否有可能一些叶子交替位于彼此之下或之上?
是否有特殊参数可以允许这样做?
非常感谢您的帮助。
答案1
forest
在优化节点布局方面表现更好。下面是代码生成的树(右侧)和第一次尝试创建树的比较forest
:
第一次通过
\documentclass{standalone}
\usepackage{forest}
\usetikzlibrary{shapes.geometric}
\begin{document}
\pgfkeys{/forest,
principal/.append style={rectangle, minimum height=5mm},
block/.append style={rectangle, fill=blue!20, text width=5em, rounded corners, minimum height=5mm},
decision/.append style={diamond, fill=blue!20, text width=5em, inner sep=.5pt},
io/.append style={trapezium, trapezium left angle=70,trapezium right angle=-70, minimum height=5mm},
op/.append style={rectangle, text width=5em, minimum height=5mm},
sequence/.append style={ellipse, fill=red!20, minimum height=5mm},
nop/.append style={ellipse, fill=red!5, minimum height=5mm},
sfstyle/.append style={font=\sffamily\large},
}
\begin{forest}
for tree={
thick,
draw,
scale=0.9,
align=center,
child anchor=north,
parent anchor=south,
every node/.style={font=\large},
}
[{Principal\\\hline entier i,j\\reel j}, principal
[POUR, sequence
[{chaque i\\de 1 a\\4 pas 1}, decision, sfstyle]
[repeter, sequence, sfstyle
[{j $\leftarrow$ LIRE()}, io, sfstyle ]
]
]
[{i $\leftarrow 1$}, op, sfstyle]
[TQ, sequence
[{($i <= 4$)}, decision, sfstyle]
[repeter, sequence, sfstyle
[ECRIRE i, io, sfstyle ]
]
]
[SI, sequence
[{($i <= 10$)}, decision, sfstyle]
[si vrai, sequence, sfstyle
[{j $\leftarrow 10$}, op, sfstyle]
[{j $\leftarrow 10$}, op, sfstyle]
[{j $\leftarrow 10$}, op, sfstyle]
]
[si faux, sequence, sfstyle
[{j $\leftarrow 12$}, op, sfstyle]
[{j $\leftarrow 12$}, op, sfstyle]
[{j $\leftarrow 12$}, op, sfstyle]
[SI, sequence
[{($i <= 10$)}, decision, sfstyle]
[si vrai, sequence, sfstyle
[{j $\leftarrow 10$}, op, sfstyle]
]
[si faux, sequence, sfstyle
[{j $\leftarrow 12$}, op, sfstyle]
]
]
]
]
]
\end{forest}
\end{document}
第二遍
这并不完美,但它将更多的间距和打包转移到了 ,从而forest
产生了更紧凑的树。然而,这确实引发了一个错误,我不确定如何解决:使用ellipse
。如果我尝试使用这些样式整理树,我会收到有关超出 TeX 最大尺寸的错误。如果我尝试delay
应用节点选项(模糊地尝试遵循第 27 页上的示例),那么一切都会变得疯狂,因为我只是得到了节点选项,而不是节点内容。虽然我得到了椭圆,但它们很大。我相信解决方案对专家来说很明显,forest
但就目前而言,我只是使用了阴影。或者,圆形也可以。(不清楚为什么椭圆有问题 - 梯形:OK,菱形:OK,圆形:OK,椭圆:??!!!??!!!)。它似乎需要说明最小高度等,但它也希望所有其他节点都这样?!
\documentclass{standalone}
\usepackage{forest}
\usetikzlibrary{shapes.geometric}
\begin{document}
\pgfkeys{/forest,
decision/.append style={diamond, fill=blue!20, text width=5em, inner sep=.5pt},
io/.append style={trapezium, trapezium left angle=70,trapezium right angle=-70, minimum height=5mm},
sequence/.append style={fill=red!20},
nop/.append style={fill=red!5},
}
\begin{forest}
for tree={
child anchor=north,
parent anchor=south,
thick,
draw,
align=center,
rounded corners,
font=\sffamily\large,
},
[{Principal\\\hline \mbox{}\\[-1em]entier i,j\\reel j}
[POUR, sequence
[{chaque i\\de 1 a\\4 pas 1}, decision]
[repeter, sequence
[{j $\leftarrow$ LIRE()}, io ]
]
]
[{i $\leftarrow 1$}, yshift=-1em]
[TQ, sequence
[{($i <= 4$)}, decision]
[repeter, sequence
[ECRIRE i, io ]
]
]
[SI, sequence
[{($i <= 10$)}, decision]
[si vrai, sequence
[{j $\leftarrow 10$}]
[{j $\leftarrow 10$}]
[{j $\leftarrow 10$}]
]
[si faux, sequence
[{j $\leftarrow 12$}]
[{j $\leftarrow 12$}]
[{j $\leftarrow 12$}]
[SI, sequence
[{($i <= 10$)}, decision]
[si vrai, sequence
[{j $\leftarrow 10$}]
]
[si faux, sequence
[{j $\leftarrow 12$}]
]
]
]
]
]
\end{forest}
\end{document}
如果有人知道如何正确使用椭圆,请发表评论!请注意,冲突似乎涉及所有节点的指定child anchor
,parent anchor
包括指定ellipse
和不指定高度等。