5

I need to illustrate a 2D array data structure in my document. This is a picture I found on the internet. I want something similar.

enter image description here

I also want to show the memory layout in the illustration. Something like this: enter image description here

Can someone help me with drawing them in Tikz? Thanks in advance.

MWE

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{matrix,backgrounds}

\begin{document}
\begin{tikzpicture}[font=\ttfamily,
array/.style={matrix of nodes,nodes={draw, minimum size=7mm, fill=green!30},column sep=-\pgflinewidth, row sep=0.5mm, nodes in empty cells,
row 1/.style={nodes={draw=none, fill=none, minimum size=5mm}},
row 1 column 1/.style={nodes={draw}}}]

\matrix[array] (array) {
0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9\\
  &   &   &   &   &   &   &   &   &  \\};
\node[draw, fill=gray, minimum size=4mm] at (array-2-9) (box) {};

\begin{scope}[on background layer]
\fill[green!10] (array-1-1.north west) rectangle (array-1-10.south east);
\end{scope}

\draw (array-1-1.north)--++(90:3mm) node [above] (first) {First index};
\draw (array-1-10.east)--++(0:3mm) node [right]{Indices};
\node [align=center, anchor=south] at (array-2-9.north west|-first.south) (8) {Element\\ (at index 8)};
\draw (8)--(box);
%
\end{tikzpicture}
\\
\begin{tikzpicture}[font=\ttfamily,
array/.style={matrix of nodes,nodes={draw, minimum size=7mm, fill=red!30},column sep=-\pgflinewidth, row sep=0.5mm, nodes in empty cells,
row 1/.style={nodes={draw=none, fill=none, minimum size=5mm}},
row 1 column 1/.style={nodes={draw}}}]

\matrix[array] (array) {
 &  &  &  &  &  &  &  &  & \\
 &   &   &   &   &   &   &   &   &  \\};
%
\end{tikzpicture}
\\
\begin{tikzpicture}[font=\ttfamily,
array/.style={matrix of nodes,nodes={draw, minimum size=7mm, fill=blue!30},column sep=-\pgflinewidth, row sep=0.5mm, nodes in empty cells,
row 1/.style={nodes={draw=none, fill=none, minimum size=5mm}},
row 1 column 1/.style={nodes={draw}}}]

\matrix[array] (array) {
 &  &  &  &  &  &  &  &  & \\
 &   &   &   &   &   &   &   &   &  \\};
%
\end{tikzpicture}
\end{document}
3
  • It would be better to visualize if the rows of the 2D array are mapped to the memory by colors than with ovals and arrows.
    – progammer
    Commented May 3, 2017 at 7:14
  • @CarLaTeX So far, I have looked into all the related questions on TeX SE. I don't have a MWE because I don't know how to proceed. I have some snippets which give 1D arrays, but that's all I have.
    – progammer
    Commented May 3, 2017 at 7:16
  • 3
    Not exactly what you want, but it can serve as inspiration: tex.stackexchange.com/a/236098/1952
    – Ignasi
    Commented May 3, 2017 at 7:19

2 Answers 2

3

A pure TikZ version

\documentclass[tikz, margin=2mm]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{matrix,backgrounds,positioning}

\begin{document}
\begin{tikzpicture}[%
    arraynode/.style={
        draw,
        node contents={[\the\numexpr\pgfmatrixcurrentrow-2\relax][\the\numexpr\pgfmatrixcurrentcolumn-2\relax]},
        alias=n\the\numexpr\pgfmatrixcurrentrow-2\relax\the\numexpr\pgfmatrixcurrentcolumn-2\relax
        },
    columnlabel/.style={
        minimum size=0pt,
        draw=none,
        red,
        node contents={\the\numexpr\pgfmatrixcurrentcolumn-2\relax},
        alias=c\the\numexpr\pgfmatrixcurrentcolumn-2\relax
        },      
    rowlabel/.style={
        minimum size=0pt,
        draw=none,
        red,
        node contents={\the\numexpr\pgfmatrixcurrentrow-2\relax},
        alias=r\the\numexpr\pgfmatrixcurrentrow-2\relax
        },      
    emptynode/.style={node contents=~, draw=none},
    font=\ttfamily,
    array/.style={%
        matrix of nodes,
        nodes = arraynode,
        column sep=-\pgflinewidth,
        row sep=-\pgflinewidth, 
        nodes in empty cells,
        row 1/.style={nodes=columnlabel},
        column 1/.style={nodes=rowlabel},
        row 1 column 1/.style={%
            nodes=emptynode}}, 
    rowlabel2/.style={
        inner sep=2pt,
        draw=none,
        font=\small\ttfamily,
        node contents={\the\numexpr99+\pgfmatrixcurrentcolumn\relax},
        alias=m\the\numexpr99+\pgfmatrixcurrentcolumn\relax
        },      
    memoryrow/.style={%
        matrix of nodes,
        row 1/.style={nodes = {draw, minimum size=7mm}},
        column sep=-\pgflinewidth,
        row sep=-\pgflinewidth, 
        nodes in empty cells,
        row 2/.style={nodes=rowlabel2}}, 
    memory/.style={%
        matrix of nodes,
        nodes={draw, minimum size=6mm, anchor=center},
        row 1/.style={nodes = {columnlabel, black}},
        column 1/.style={nodes = {rowlabel, black}},
        row 1 column 1/.style={nodes = emptynode},
        column sep=-\pgflinewidth,
        row sep=-\pgflinewidth, 
        nodes in empty cells,
    } 
]

\matrix[array] (array) {
&&&&\\
&&&&\\
&&&&\\
&&&&\\};

\node[above= 4mm of n01.north east] {Columns};
\node[left= 0mm of r1, rotate=90, anchor=south] {Rows};
\draw[<-] (c0.west)--++(130:1cm) node[above, draw]{2nd subscript};
\draw[<-] (r2.south)--++(250:1cm) node[below, draw]{1st subscript};
\draw[<-] ([shift={(-1mm,-1mm)}]n02.north east)--++(65:2cm) node[above, draw, text width=3cm]{Element's subscript order};

\begin{scope}[yshift=-4cm]

\matrix[memoryrow] (memrow) {
&&&&&&&&&&&&&&&&\\
&&&&&&&&&&&&&&&&\\};

\node[above right=1mm and 0 of memrow-1-1.north west] {Memory};
\draw[thick] (memrow-1-1.north west) rectangle (memrow-1-17.south east);

\matrix[memory, below left=8mm and 0 of memrow, anchor=north west] (memory) {
&&&\\
&&&\\
&&&\\
&&&\\};

\begin{scope}[on background layer]
\fill[red!30] (memrow-1-3.north west) rectangle (memrow-1-5.south east);
\fill[blue!30] (memrow-1-6.north west) rectangle (memrow-1-8.south east);
\fill[green!30] (memrow-1-9.north west) rectangle (memrow-1-11.south east);
\fill[red!30] (memory-2-2.north west) rectangle (memory-2-4.south east);
\fill[blue!30] (memory-3-2.north west) rectangle (memory-3-4.south east);
\fill[green!30] (memory-4-2.north west) rectangle (memory-4-4.south east);
\end{scope}
\draw[->] (memory-2-4) to[out=0, in=-90] (memrow-1-4.center);
\draw[->] (memory-3-4) to[out=0, in=-90] (memrow-1-7.center);
\draw[->] (memory-4-4) to[out=0, in=-90] (memrow-1-10.center);
\end{scope}

\end{tikzpicture}
\end{document}

enter image description here

0
5

The code below illustrates two methods. The first draws the table as ordinary tabular, marks some places with \tikznode and then annotates the table using a tikzpicture in overlay mode. The second method draws everything in a tikzpicture. The first method is useful if you want to use the annotated stuff (here the tabular) within normal text, the second one creates a standalone picture with no access to its elements from the outside.

enter image description here

\documentclass{article}
\usepackage{tikz}% for drawing arrows and boxes, provides also \color
\usepackage{multirow}% for the \multirow command
\usepackage{rotating}% for the sideways environment

% no vertical lines - centered cell without vertical line
\newcommand\nvl[1]{\multicolumn{1}{c}{#1}}
% red centered cell without vertical line
\newcommand\redhead[1]{\nvl{\color{red}#1}}
% memory address
\newcommand\ma[1]{\nvl{\scriptsize#1}}

% \tikznode[options]{label}{contents}
\newcommand\tikznode[3][]%
   {\tikz[remember picture,baseline=(#2.base)]
      \node[minimum size=0pt,inner sep=0pt,#1](#2){#3};%
   }

\begin{document}

{\renewcommand\arraystretch{1.3}
\begin{tabular}{c@{\hspace{5pt}}c|c|c|c|c|}
  &\redhead{}&\multicolumn{4}{c}{columns}
\\[-3pt]
  &\redhead{}&\redhead{\tikznode{B}{0}} & \redhead{1} & \redhead{2} & \redhead{3}
\\\cline{3-6}
  \multirow{3}{*}{\begin{sideways}rows\end{sideways}}
  & \color{red}0 & [0][0] & [0][1] & \tikznode{C}{[0][2]} & [0][3]
\\\cline{3-6}
  & \color{red}1 & [1][0] & [1][1] & [1][2] & [1][3]
\\\cline{3-6}
  & \color{red}\tikznode{A}{2} & [2][0] & [2][1] & [2][2] & [2][3]
\\\cline{3-6}
\end{tabular}}
\begin{tikzpicture}[remember picture,overlay,>=stealth]
  \draw[<-,shorten <=1pt] (A) -- +(-1,-1) node[draw,left] {1st subscript};
  \draw[<-,shorten <=1pt] (B) -- +(-1,1) node[draw,left]{2nd subscript};
  \draw[<-,shorten <=1pt] (C) -- +(0.5,1.5) node[draw,right,align=left]{subscript order\\of elements};
\end{tikzpicture}

\end{document}

enter image description here

\documentclass[border=2pt]{article}
\usepackage{tikz}
\usetikzlibrary{fit,shapes}
\begin{document}

\begin{tikzpicture}
  [x=5mm,y=5mm,
   cell/.style={draw,minimum size=5mm,inner sep=0pt},
   3cells/.style={ellipse,draw,minimum width=1.2cm},
   >=stealth
  ]
  \foreach \l [count=\i] in {100,...,116}
     \node[cell,label=below:\scriptsize\l] (c\i) at (\i-1,0) {};
  \node[cell,thick,fit=(c1)(c17)] {};
  \foreach \i in {4,7,10}
     \node[3cells] (C\i) at (c\i) {};
  \begin{scope}[shift={(0,-5)}]
  \foreach \i in {0,1,2}
     \foreach \j in {0,1,2} \node[cell] (g\i\j) at (\j,-\i) {};
  \node[cell,thick,fit=(g00)(g22)] {};
  \foreach \i in {0,1,2} \node[cell,draw=none] at (-1,-\i) {\i};
  \foreach \i in {0,1,2} \node[cell,draw=none] at (\i,1) {\i};
  \foreach \i in {0,1,2} \node[3cells] (G\i) at (g\i1) {};
  \end{scope}
  \foreach \i/\j in {0/4,1/7,2/10} \draw[->] (G\i) -- (C\j);
\end{tikzpicture}

\end{document}
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .