我需要说明一个链接列表和添加一个元素,有没有什么方法可以停止并继续 foreach 循环或暂停链,这样它就不会连接元素 5 和 6?
\documentclass{article}
\usepackage{pgffor}
\usepackage{tikz}
\usepackage{xfp}
\usepackage{mathtools}
\usetikzlibrary{calc, shapes.multipart,chains,arrows,positioning}
\tikzstyle{strela} = [thick, ->, >=stealth]
\newcommand\x{9}
\newcommand\y{3}
\newcommand\m{5}
\begin{document}
\begin{tikzpicture}[ar/.style={*->,shorten <=-.28cm},list/.style={rectangle split, rectangle split parts=2, draw, rectangle split horizontal,join=by ar}, start chain=going right]
\foreach \i in {3,...,\the\numexpr\x}{
\node[list,on chain] (\the\numexpr\i) {\i};
}
\node (strela2) [strela, below of= 3, xshift=-0.5cm, yshift=-0.7cm]{HEAD};
\draw (strela2) -> (3);
\node (strela3) [strela, below of= \the\numexpr\x, xshift=-0.5cm, yshift=-0.7cm] {TAIL};
\draw (strela3) -> (\the\numexpr\x);
\node (obj) [right of= \the\numexpr\x,draw,inner sep=6pt] (D) {};
\draw (D.north east) -- (D.south west);
\draw (D.north west) -- (D.south east);
\draw [*->, shorten <=+.10cm] (\the\numexpr\x.center) -- (D);
\node (strela5) [strela, below of= D, yshift=-0.72cm] {NULL};
\draw (strela5) -> (D);
\node[list,below of= \the\numexpr\m, xshift=+1cm] (A) {\the\numexpr\m+0.5};
\end{tikzpicture}
\begin{flushleft}
\vspace{2cm}
\end{flushleft}
\begin{tikzpicture}[ar/.style={*->,shorten <=-.28cm},list/.style={rectangle split, rectangle split parts=2, draw, rectangle split horizontal,join=by ar}, start chain=going right]
\foreach \i in {3,...,\the\numexpr\x/2}{
\node[list,on chain] (\the\numexpr\i) {\i};
}
\node[list,below of= \the\numexpr\m, xshift=+1cm] (A) {\the\numexpr\m+0.5};
\draw[*->] let \p1 = (\the\numexpr\m.two), \p2 = (\the\numexpr\m.center) in (\x1,\y2) -- (A);
\draw[*->] let \p1 = (A.two), \p2 = (A.center) in (\x1,\y2) -- (\the\numexpr\m+1);
\foreach \k in {\the\numexpr\x/2 + 1,...,\the\numexpr\x}{
\node[list, on chain] (\the\numexpr\i) {\k};
}
\node (strela2) [strela, below of= 3, xshift=-0.5cm, yshift=-0.7cm]{HEAD};
\draw (strela2) -> (3);
\end{tikzpicture}
\end{document}
答案1
您可以测试当前号码并根据此测试添加连接。
与您的问题无关:不要使用已弃用的\tikzstyle
,您可以改用\tikzset
。
\documentclass{article}
\usepackage{pgffor}
\usepackage{tikz}
\usepackage{xfp}
\usepackage{mathtools}
\usetikzlibrary{calc, shapes.multipart,chains,arrows,positioning}
\tikzset{strela/.style={thick, ->, >=stealth}}
\newcommand\x{9}
\newcommand\y{3}
\newcommand\m{5}
\begin{document}
\begin{tikzpicture}[ar/.style={*->,shorten <=-.28cm},list/.style={rectangle split, rectangle split parts=2, draw, rectangle split horizontal}, start chain=going right]
\foreach \i in {3,...,\the\numexpr\x}{
\ifnum\i=6
\node[list,on chain] (\the\numexpr\i) {\i};
\else
\node[list,on chain,join=by ar] (\the\numexpr\i) {\i};
\fi
}
\end{tikzpicture}
\end{document}
答案2
解决方案 1
\foreach \i in {3, ..., 9}
\node[list, on chain,
/utils/TeX/ifnum={\i=6}{}{join=by ar}
] {\i};
与 samcarter 的答案类似,它只是移动\ifnum
节点内部的选项,这样您就不必编写冗余代码。
没有ext.misc
你也可以达到几乎相同的效果
\node[list, on chain, style/.expanded={\ifnum\i=6 \else join=by ar\fi}] {\i};
但有点乱。
样式ar*
定义为
ar*/.style={
to path={[insert path/.expanded={
edge[path only, line to]
node[list,below=5mm] (@) {\unexpanded{#1}} (\tikztotarget)
(\tikztostart) edge[ar] (@)
(@) edge[ar] (\tikztotarget)}]}}
你可以做
\node[list, on chain,
/utils/TeX/ifnum={\i=6}{join=by {ar*={5,5}}}{join=by ar}
] {\i};
甚至得到
不需要做太多工作(不过,我建议增加text depth=0pt
风格list
)。
解决方案 2 只是尝试了一些可能会禁用该join
键的样式。这也意味着join?=\i
(或只是kill join \i/.try
)需要在实际join
键之前。(不幸的是,没有“干净”的方法来脱离节点但这看起来很简单。
处理程序允许您快速给出不应该加入.list
的列表。\i
ar*
相反,仅使用非常具体的依赖键可能同样可以添加连接\i
。
代码
\documentclass[varwidth]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc, shapes.multipart, chains, arrows.meta}
\tikzset{every picture/.append style={
node distance=5mm,
*/.tip={Circle[sep=-1.196825pt -1.595769]},
ar/.style={*->, to path={($(\tikztostart.two south)!.5!(\tikztostart.two north)$) -- (\tikztotarget)}},
ar*/.style={
to path={[insert path/.expanded={
edge[path only, line to]
node[list,below=5mm] (@) {\unexpanded{##1}} (\tikztotarget)
(\tikztostart) edge[ar] (@)
(@) edge[ar] (\tikztotarget)}]}},
list/.style={rectangle split, rectangle split parts=2, draw, rectangle split horizontal},
start chain=going right}}
% Solution 1:
\usetikzlibrary{ext.misc}
% Solution 2:
\tikzset{
join?/.style={kill join on #1/.try},
don't join on/.style={
kill join on #1/.style={join/.code=}}}
\begin{document}
% Solution 1:
\tikz\foreach \i in {3, ..., 9}
\node[list, on chain,
/utils/TeX/ifnum={\i=6}{join=by {ar*={5,5}}}{join=by ar}
] {\i};
\\
% Solution 1 without ext.misc
\tikz\foreach \i in {3, ..., 9}
\node[list, on chain, style/.expanded={\ifnum\i=6 \else join=by ar\fi}] {\i};
\\
% Solution 2:
\tikz[don't join on=6]\foreach \i in {3, ..., 9}
\node[list, on chain, join?=\i, join=by ar] {\i};
\\
% Solution 2 with more than one:
\tikz[don't join on/.list={4,6,8}]\foreach \i in {3, ..., 9}
\node[list, on chain, join?=\i, join=by ar] {\i};
\end{document}