[Tex/LaTex] Typesetting Sorting Diagrams

diagrams

I am typesetting some diagrams representing sorting algorithms similar to those found in Miller and Ranum Python Book partly as an exercise in learning TikZ. I'm trying to typeset something similar to the Merge sort diagrams:

Splitting phase:

Splitting phase diagram

Merging phase

Merging phase diagram

I started with a multipart rectangle but the drop shadow overwrites the filled nodes (unless white) — on the second row I experimented with individual nodes but this leads to problems with fonts (such as Lucida) where not all digits have the dame height.

Here's my code for these parts:

\documentclass[12pt]{article}

\usepackage{tikz}
\usetikzlibrary{arrows}
\usetikzlibrary{shapes.geometric}
\usetikzlibrary{shapes.multipart}
\usetikzlibrary{shadows}
\usetikzlibrary{positioning}

\newlength{\OUmatrixSepWidth}
\newcommand{\OUsetMatrixSepWidth}[1]{%
  \settowidth{\OUmatrixSepWidth}{#1}%
}

\renewcommand{\familydefault}{\sfdefault}
\thispagestyle{empty}

\begin{document}
\Large  

  \OUsetMatrixSepWidth{3em}

  \begin{tikzpicture}
    [myInnerBlock/.style={rectangle,draw,align=center}
    ,myInnerBlockL/.style={rectangle,draw,align=center,fill=red!20}
    ,myInnerBlockR/.style={rectangle,draw,align=center,fill=blue!20}
    ,myRectangleSplit/.style={rectangle split,rectangle split horizontal,draw,rectangle split part align={center,base}} % requires library shapes.multipart
    ,line/.style={draw,thick,red,-triangle 60}
    ]
    \matrix[column sep=0.3\OUmatrixSepWidth, row sep=0.5\OUmatrixSepWidth]
    {
      % row 1
      \node[myRectangleSplit,rectangle split allocate boxes=10,rectangle split parts=10,drop shadow,rectangle split part fill={red!20,red!20,red!20,red!20,red!20,blue!20}] (unsorted) 
      { 3\nodepart{two}0\nodepart{three}1\nodepart{four}8\nodepart{five}7\nodepart{six}2\nodepart{seven}5\nodepart{eight}4\nodepart{nine}9\nodepart{ten}6}; \\
      % row 2
      \node (r2ac) {}; 
      \node[myInnerBlockR,left=0.3\OUmatrixSepWidth of r2ac] (r2a5) {7}; 
      \node[myInnerBlockR,left=0pt of r2a5] (r2a4) {8}; 
      \node[myInnerBlockR,left=0pt of r2a4] (r2a3) {1}; 
      \node[myInnerBlockL,left=0pt of r2a3] (r2a2) {0}; 
      \node[myInnerBlockL,left=0pt of r2a2] (r2a1) {3}; 
      \node[myInnerBlockL,right=0.3\OUmatrixSepWidth of r2ac] (r2a6) {2}; 
      \node[myInnerBlockL,right=0pt of r2a6] (r2a7) {5}; 
      \node[myInnerBlockR,right=0pt of r2a7] (r2a8) {4}; 
      \node[myInnerBlockR,right=0pt of r2a8] (r2a9) {9}; 
      \node[myInnerBlockR,right=0pt of r2a9] (r2a10) {6}; 
      \\
      % row 3
      % row 4
      % row 5
    }; 
  \end{tikzpicture}


\end{document}    

Which looks like:

Query Image Output

The multipart rectangle would appear nicer but how do you get the drop shadow to not overwrite the rectangle? Is there a better way that I'm missing ? Would a tree structure be easier ? Not to mention getting the lines with right angles.

Best Answer

Using your code and the answer from here: Drawing a proper shadow for overlapping objects, and adjusting the shadow yshift key, you can have shadows properly drawn. For extra info about shadows see page 415 on PGF manual.

\documentclass[12pt]{article}

\usepackage{tikz}
\usetikzlibrary{arrows}
\usetikzlibrary{shapes.geometric}
\usetikzlibrary{shapes.multipart}
\usetikzlibrary{shadows}
\usetikzlibrary{positioning}

\newlength{\OUmatrixSepWidth}
\newcommand{\OUsetMatrixSepWidth}[1]{%
  \settowidth{\OUmatrixSepWidth}{#1}%
}

\renewcommand{\familydefault}{\sfdefault}
\thispagestyle{empty}

\pgfdeclarelayer{back}
\pgfsetlayers{back,main}
\makeatletter
\pgfkeys{%
  /tikz/on layer/.code={
    \pgfonlayer{#1}\begingroup
    \aftergroup\endpgfonlayer
    \aftergroup\endgroup
  },
  /tikz/node on layer/.code={
    \pgfonlayer{#1}\begingroup
    \expandafter\def\expandafter\tikz@node@finish\expandafter{\expandafter\endgroup\expandafter\endpgfonlayer\tikz@node@finish}%
  },
}
\makeatother

\begin{document}
\Large  

  \OUsetMatrixSepWidth{3em}

  \begin{tikzpicture}
    [myInnerBlock/.style={rectangle,draw,align=center}
    ,myInnerBlockL/.style={rectangle,draw,align=center,fill=red!20}
    ,myInnerBlockR/.style={rectangle,draw,align=center,fill=blue!20}
    ,myRectangleSplit/.style={rectangle split,rectangle split horizontal,draw,rectangle split part align={center,base}} % requires library shapes.multipart
    ,line/.style={draw,thick,red,-triangle 60}
    ]
    \matrix[column sep=0.3\OUmatrixSepWidth, row sep=0.5\OUmatrixSepWidth]
    {
      % row 1
      \node[myRectangleSplit,rectangle split allocate boxes=10,rectangle split parts=10,drop shadow={on layer=back,shadow yshift
=3ex},rectangle split part fill={red!20,red!20,red!20,red!20,red!20,blue!20}] (unsorted) 
      { 3\nodepart{two}0\nodepart{three}1\nodepart{four}8\nodepart{five}7\nodepart{six}2\nodepart{seven}5\nodepart{eight}4\nodepart{nine}9\nodepart{ten}6}; \\[2ex]
      % row 2
      \node (r2ac) {}; 
      \node[myInnerBlockR,left=0.3\OUmatrixSepWidth of r2ac] (r2a5) {7}; 
      \node[myInnerBlockR,left=0pt of r2a5] (r2a4) {8}; 
      \node[myInnerBlockR,left=0pt of r2a4] (r2a3) {1}; 
      \node[myInnerBlockL,left=0pt of r2a3] (r2a2) {0}; 
      \node[myInnerBlockL,left=0pt of r2a2] (r2a1) {3}; 
      \node[myInnerBlockL,right=0.3\OUmatrixSepWidth of r2ac] (r2a6) {2}; 
      \node[myInnerBlockL,right=0pt of r2a6] (r2a7) {5}; 
      \node[myInnerBlockR,right=0pt of r2a7] (r2a8) {4}; 
      \node[myInnerBlockR,right=0pt of r2a8] (r2a9) {9}; 
      \node[myInnerBlockR,right=0pt of r2a9] (r2a10) {6}; 
      \\
      % row 3
      % row 4
      % row 5
    }; 
  \end{tikzpicture}


\end{document} 

Result:

enter image description here