5

I have done a doubly linked list as below but I still not satisfy the label annotation of begin and end. I know it's a bad style now but don't how simplify it.

\documentclass{article}
\usepackage[pdftex,active,tightpage]{preview}
\setlength\PreviewBorder{2mm}

\usepackage{xifthen}
\usepackage{tikz}
\usetikzlibrary{calc,shapes.multipart,chains,arrows,positioning}

\begin{document}
\begin{preview}
\tikzset{>=latex}
\def\N{6}
\begin{tikzpicture}[
  list/.style={
    very thick, rectangle split, 
    rectangle split parts=3, draw, 
    rectangle split horizontal, minimum size=18pt,
    inner sep=5pt, text=black,
    rectangle split part fill={blue!20, red!20, blue!20}
  }, 
  ->, start chain=M0 circle placed {at=(\tikzchaincount*360/\N:2.5cm)},very thick
  ]    
  \foreach \i in {1,...,\N} {
    \node[list,on chain,rotate={360*\i/\N-90}] (P\i) {\nodepart{second} $P_{\i}$};
  }

  \foreach \i [evaluate=\i as \j using int(\i+1)] in {1,...,\N} {
    \ifthenelse{\i=\N} {\pgfmathsetmacro\j{1}}{}
    \path[*->,red] (P\j.three) edge [bend left] (P\i.north west);
    \path[*->,blue] (P\i.one) edge [bend left] (P\j.south east);
  }
  \draw[->,rotate=360/\N-90] ([yshift=1cm]P1.north) -- node [above,rotate=360/\N] {begin} (P1.north);
  \draw[->,rotate=-90] ([yshift=1cm]P\N.north) -- node [above,rotate=0] {end} (P\N.north);
  \draw[->,dashed] (360/\N:2cm) arc (360/\N:270:2cm);
\end{tikzpicture}
\end{preview}
\end{document}

Wish to improve:

  1. Can we use a Mod to replace the ifthenelse statement?
  2. The label seems need to rotate the same as the rectangle, can we just do it the same with rectangle then only need to rotate one time.

Output:

enter image description here

  • 1
    Maybe use polar coordinate system? – lucky1928 May 4 '15 at 3:55
  • 1
    If it's a problem with label annotation style, please explain what would like you? If it's a problem with your TikZ style, try with \draw[<-] (P1.north) --node[sloped,above]{begin} ($(P1.north)!1.5cm!90:(P1.north east)$); although I don't know what's wrong with your solution. It does what you want. – Ignasi May 4 '15 at 8:20
2

I hope I understood correctly what you wanted to do. Additionaly to your two points of concern I also made it scale with the number of nodes, but it becomes a giant graph pretty fast.

Code

\documentclass[tikz, border=2mm]{standalone}
\usetikzlibrary{calc,shapes.multipart,chains,arrows,positioning}

\begin{document}
\tikzset{>=latex}
\def\N{11}
\begin{tikzpicture}
[   list/.style=
    {   very thick, draw, minimum size=18pt, inner sep=5pt, text=black,
    rectangle split, rectangle split parts=3, rectangle split horizontal, 
    rectangle split part fill={blue!20, red!20, blue!20}
  }, 
  ->, start chain=M0 circle placed {at=(\tikzchaincount*360/\N:{1.25/sin(180/\N)})}, very thick
]    
  \foreach \i in {1,...,\N} {
    \node[list,on chain, rotate={360*\i/\N-90}] (P\i) {\nodepart{second} $P_{\i}$};
  }

  \foreach \i in {1,...,\N} {
    \pgfmathtruncatemacro{\j}{mod(\i,\N)+1}
    \path[*->,red] (P\j.three) edge [bend left] (P\i.north west);
    \path[*->,blue] (P\i.one) edge [bend left] (P\j.south east);
  }
  \draw[->] (P1.north) -- node [above, sloped] {begin} ++ (360/\N:2cm);
  \draw[->] (P\N.north) -- node [above, sloped] {end} ++ (360:2cm);

  \draw[->,dashed] (360/\N:{1.25/sin(180/\N)*0.8}) arc (360/\N:270:{1.25/sin(180/\N)*0.8});
\end{tikzpicture}
\end{document}

Output

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.