TeX - LaTeX Asked on August 11, 2021
I would like draw a linked-list example as on the following figure. Idea is similiar to solution for How should I draw a singly/double linked list?, but I wasn’t able to do the arrowing from north node to south node.
I have used following example for How to make a graph (nodes and edges) on Latex? .
Minimal code that I tried:
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}
Usually anything that looks like a matrix can be made more easily with a TikZ matrix. And usually a TikZ matrix is easier than the cumbersome placement of single nodes.
1. The picture from the startpost:
documentclass[margin=5pt, tikz]{standalone}
usepackage{tikz}
usetikzlibrary{matrix}
begin{document}
begin{tikzpicture}[font=footnotesizesffamily,
>=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=htstrutbox,
text depth=dpstrutbox,
text width =1.5htstrutbox,
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. With variable numbers of rows and columns:
There is no key like row last/.style=...
so you need to create them and then use some tricks due to the expanding order:
documentclass{article}
usepackage{tikz}
usetikzlibrary{matrix}
makeatletter
tikzset{store number of columns in/.style={execute at end matrix={
xdef#1{thepgf@matrix@numberofcolumns}}},
store number of rows in/.style={execute at end matrix={
xdef#1{thepgfmatrixcurrentrow}}}}
makeatother
begin{document}
% Wrong start values
deflastrow{1}
deflastcol{1}
deflastcolP{1}
newcommandmymatrix{%%%
begin{tikzpicture}[font=footnotesizesffamily,
>=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=htstrutbox,
text depth=dpstrutbox,
text width =1.5htstrutbox,
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.
pgfmathtruncatemacrolastcolP{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}
Correct answer by cis on August 11, 2021
Here you go, I'm using the positioning
library to achieve it without a bunch of extra commands setting up coordinates.
Your code had an error with the square
style; I removed the term `square' as it appears to not do anything to your code.
I've included the text above the tail box in case you wish to use it (as I see you've already written 'tail' inside the box).
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}
Answered by pikopiko on August 11, 2021
This is not really an answer but I agree with this answer by pikopiko that it is better not position anything by hand. So out of many possibilities that allow you to avoid manual positioning here is one using a matrix
.
documentclass[tikz,margin=3]{standalone}
usepackage{sansmath}
usetikzlibrary{fit,matrix,positioning,shadows}
begin{document}
begin{tikzpicture}[font=sffamilysansmath,
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 ifnumy=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}
Answered by user227987 on August 11, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP