我想画一个链表示例,如下图所示。想法类似于以下解决方案我应该如何绘制单/双链表?,但我无法从北交点到南交点画出箭头。
我已经使用以下示例如何在 Latex 上制作图形(节点和边)?。
- 我无法将标签放在框旁边,然后用虚线指向它们。还有虚线矩形覆盖顶部的三个框。
我尝试过的最少代码:
\documentclass[tikz,margin=3]{standalone}
\usetikzlibrary{shadows} % Shadows for nodes
\begin{document}
\begin{tikzpicture}
\tikzset{% This is the style settings for nodes
dep/.style={square,minimum size=1cm,fill=orange!20,draw=orange,
general shadow={fill=gray!60,shadow xshift=1pt,shadow yshift=-1pt}},
cli/.style={square,minimum size=1cm,fill=white,draw,
general shadow={fill=gray!60,shadow xshift=1pt,shadow yshift=-1pt}},
spl/.style={square,append after command={
node[circle,draw,dotted,
minimum size=1.5cm] at (\tikzlastnode.center) {}}},
c1/.style={-stealth,very thick,black!80!black},
v2/.style={-stealth,very thick,yellow!65!black},
v4/.style={-stealth,very thick,purple!70!black}}
\node[dep] (1) at (0,0) {0};
\node[dep] (2) at (2,0) {4};
\node[dep] (3) at (4,0) {10};
%
\node[cli] (16) at (6,0) {tail};
\node[cli] (7) at (0,-2) {-16};
\node[cli] (8) at (2,-2) {-16};
\node[cli] (9) at (4,-2) {-16};
%
\node[cli] (10) at (0,-3) {3};
\node[cli] (11) at (2,-3) {10};
\node[cli] (12) at (4,-3) {15};
%
\node[dep] (13) at (0,-4) {4};
\node[dep] (14) at (2,-4) {10};
\node[cli] (15) at (4,-4) {/};
\draw[c1] (1) -- (7);
\draw[c1] (2) -- (8);
\draw[c1] (3) -- (9);
\draw[c1] (16) -- (3);
\end{tikzpicture}
\end{document}
答案1
通常,任何看起来像矩阵的东西都可以用 TikZ 矩阵更轻松地制作。而且通常 TikZ 矩阵比繁琐的单个节点放置更容易。
1. 来自startpost的图片:
\documentclass[margin=5pt, tikz]{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}[font=\footnotesize\sffamily,
>=stealth,
]
\matrix (m) [matrix of nodes, nodes in empty cells,
nodes={draw, %thick,
%inner sep=0pt, outer sep=0pt,
%minimum width=1.9em,
text height=\ht\strutbox,
text depth=\dp\strutbox,
text width =1.5\ht\strutbox,
align=center, anchor=center,
},
column sep=1em, row sep=-\pgflinewidth,
Fill/.style 2 args={row #1 column #2/.style={nodes={fill=cyan!66}}},
Fill/.list={ {5}{2}, {5}{3} },
row 1/.style={nodes={draw=none} },
column 1/.style={column sep=2em,
nodes={align=right, draw=none, text width=1cm} },
%
row 2 column 1/.style={nodes={xshift=-2mm}},
%
column 5/.style={nodes={draw=none} },
row 2 column 5/.style={nodes={draw} },
%
row 2/.style={row sep=1.5em, },
%
column 4/.style={column sep=1.75em, },
]{
& & & & tail \\
mapping & 0 & 4 & 10 & 10 \\
value & -16 & -16 & -16 & \\
point & 3 & 10 & 15 & \\
next & 4 & 10 & / & \\
%1 & 2 & 3 & 4 & 5 \\
};
% Annotations:
\foreach \col in {2,...,4}{
\draw[->] (m-2-\col) -- (m-3-\col); }
\draw[->] (m-2-5) -- (m-2-4);
\foreach \row in {3,...,5}{
\draw[shorten >=2pt] (m-\row-1) -- (m-\row-2); }
\draw[shorten >=1em] (m-2-1) -- (m-2-2);
\draw[densely dashed] ([shift={(-0.5em,0.5em)}]m-2-2.north west) rectangle ([shift={(0.5em,-0.5em)}]m-2-\lastcolP.south east);
\end{tikzpicture}
\end{document}
2. 行数和列数可变:
没有类似的键row last/.style=...
,所以您需要创建它们,然后根据扩展顺序使用一些技巧:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}
\makeatletter
\tikzset{store number of columns in/.style={execute at end matrix={
\xdef#1{\the\pgf@matrix@numberofcolumns}}},
store number of rows in/.style={execute at end matrix={
\xdef#1{\the\pgfmatrixcurrentrow}}}}
\makeatother
\begin{document}
% Wrong start values
\def\lastrow{1}
\def\lastcol{1}
\def\lastcolP{1}
\newcommand\mymatrix{%%%
\begin{tikzpicture}[font=\footnotesize\sffamily,
>=stealth,
]
\matrix (m) [matrix of nodes, nodes in empty cells,
store number of columns in=\lastcol,
store number of rows in=\lastrow,
ampersand replacement=\&,
nodes={draw, %thick,
inner sep=0pt, outer sep=0pt,
minimum width=1.9em,
text height=\ht\strutbox,
text depth=\dp\strutbox,
text width =1.5\ht\strutbox,
align=center, anchor=center,
},
column sep=1em, row sep=-\pgflinewidth,
]{
\& \& \& \& \& tail \\
mapping\& 0 \& 4 \& new \& 1 \& 10 \\
value \& -16 \& -16 \& new \& -16 \& \\
point \& 3 \& 10 \& new \& 15 \& \\
new \& new \& new \& new \& new \& \\
new \& new \& new \& new \& new \& \\
new \& new \& new \& new \& new \& \\
next \& 4 \& 10 \& new \& / \& \\
%1 \& 2 \& 3 \& 4 \& 5 \& 6 \\
};
%
% Annotations:
\foreach \col in {2,...,\lastcolP}{
\draw[->] (m-2-\col) -- (m-3-\col); }
\draw[->] (m-2-\lastcol) -- (m-2-\lastcolP);
\foreach \row in {3,...,\lastrow}{
\draw[shorten >=2pt, shorten <=2pt] (m-\row-1) -- (m-\row-2); }
\draw[shorten >=0.7em, shorten <=3pt] (m-2-1) -- (m-2-2);
\draw[densely dashed] ([shift={(-0.5em,0.5em)}]m-2-2.north west) rectangle ([shift={(0.5em,-0.5em)}]m-2-\lastcolP.south east);
\end{tikzpicture}
}%%%
\newsavebox{\mybox}
\savebox{\mybox}{\mymatrix}
\section{Wrong}
\mymatrix
\section{Still Wrong}
\usebox{\mybox} \par
Last col is: \lastcol. Last row is \lastrow.
\pgfmathtruncatemacro\lastcolP{\lastcol-1}
\tikzset{
store number of columns in=\lastcol,
store number of rows in=\lastrow,
Fill/.style 2 args={row #1 column #2/.style={nodes={fill=cyan!44}}},
Fill/.list={ {\lastrow}{2}, {\lastrow}{3} },
row 1/.style={nodes={draw=none} },
column 1/.style={column sep=2em,
nodes={align=right, draw=none, text width=1cm} },
%
row 2 column 1/.style={nodes={xshift=-2mm}},
%
column \lastcol/.style={nodes={draw=none} },
row 2 column \lastcol/.style={nodes={draw} },
%
row 2/.style={row sep=1.5em, },
%
column \lastcolP/.style={column sep=1.75em, },
}
\section{Correct}
\savebox{\mybox}{\mymatrix}
\usebox{\mybox}
\end{document}
答案2
这不是一个真正的答案,但我同意pikopiko 的这个回答最好不要手动定位任何东西。因此,在众多可让您避免手动定位的方法中,有一种是使用matrix
。
\documentclass[tikz,margin=3]{standalone}
\usepackage{sansmath}
\usetikzlibrary{fit,matrix,positioning,shadows}
\begin{document}
\begin{tikzpicture}[font=\sffamily\sansmath,
square/.style={minimum size=1cm,draw,fill=white,drop shadow},
f/.style={fill=orange!20,draw=orange},
v2/.style={-stealth,very thick,yellow!65!black}]
\matrix[matrix of math nodes,row sep=-\pgflinewidth,column sep=1.5em,
cells={nodes={square,
text depth=0.25ex,text height=1em}},
row 1/.style={nodes=f}] (m){
0 & 4 & 10 \\[2em]
-16 & -16 & -16\\
3 & 10 & 15\\
|[f]|4 & |[f]|10 & /\\
};
%
\node[draw,dashed,inner sep=1em,fit=(m-1-1)(m-1-3)](f){};
%
\node[square,right=3em of m-1-3] (t){tail};
%
\foreach \x[count=\y] in {mapping,value,point,next}
{\draw \ifnum\y=1 (f.west)
\else
(m-\y-1.west)\fi -- ++ (-2em,0) node[left]{\x};}
%
\draw[v2] (t) -- (m-1-3);
\foreach \x in {1,2,3}
{\draw[v2] (m-1-\x) -- (m-2-\x);}
\end{tikzpicture}
\end{document}
答案3
在这里,我正在使用positioning
库来实现它,而不需要一堆额外的命令来设置坐标。
您的代码样式有误square
;我删除了术语“正方形”,因为它似乎对您的代码没有任何影响。
我在尾箱上方附上了文字,以防您想使用它(因为我看到您已经在箱子里写了“尾部”)。
\documentclass[tikz,margin=3]{standalone}
\usetikzlibrary{shadows, positioning} % Shadows for nodes
\begin{document}
\begin{tikzpicture}
\tikzset{% This is the style settings for nodes
dep/.style={minimum size=1cm,fill=orange!20,draw=orange,
general shadow={fill=gray!60,shadow xshift=1pt,shadow yshift=-1pt}},
cli/.style={minimum size=1cm,fill=white,draw,
general shadow={fill=gray!60,shadow xshift=1pt,shadow yshift=-1pt}},
spl/.style={append after command={
node[circle,draw,dotted,
minimum size=1.5cm] at (\tikzlastnode.center) {}}},
c1/.style={-stealth,very thick,black!80!black},
v2/.style={-stealth,very thick,yellow!65!black},
v4/.style={-stealth,very thick,purple!70!black}}
\node[dep] (1) at (0,0) {0};
\node[dep] (2) at (2,0) {4};
\node[dep] (3) at (4,0) {10};
%
\node[cli] (16) at (6,0) {tail};
\node[cli] (7) at (0,-2) {-16};
\node[cli] (8) at (2,-2) {-16};
\node[cli] (9) at (4,-2) {-16};
%
\node[cli] (10) at (0,-3) {3};
\node[cli] (11) at (2,-3) {10};
\node[cli] (12) at (4,-3) {15};
%
\node[dep] (13) at (0,-4) {4};
\node[dep] (14) at (2,-4) {10};
\node[cli] (15) at (4,-4) {/};
\draw[c1] (1) -- (7);
\draw[c1] (2) -- (8);
\draw[c1] (3) -- (9);
\draw[c1] (16) -- (3);
% label lines next to boxes
\node[left = 0.3cm of 1] (labellineTop){};
\node[left = 0.3cm of 7] (labelline1){};
\node[left = 0.3cm of 10] (labelline2){};
\node[left = 0.3cm of 13] (labelline3){};
\draw (labelline1) -- +(-1,0);
\draw (labelline2) -- +(-1,0);
\draw (labelline3) -- +(-1,0);
\draw (labellineTop) -- +(-1,0);
% labels next to boxes
\node[left = 1.5cm of 1, align=right] {mapping};
\node[left = 1.5cm of 7, align=right] {value};
\node[left = 1.5cm of 10, align=right] {point};
\node[left = 1.5cm of 13, align=right] {next};
\node[above = 0.2cm of 16] {tail};
% dashed rectangle
\node[above left = 0.3cm of 1] (rectangleA){};
\node[below right = 0.3cm of 3] (rectangleB){};
\draw[dashed] (rectangleA) rectangle (rectangleB){};
\end{tikzpicture}
\end{document}