8

I would like to obtain easily something like in this picture so as to illustrate several sorting algorithms.

sorting

To produce one line, I would like to use one command of the following kind where the numbers of values is not fixed by advance.

\list{\style1}{value1}{\style2}{value2}{\style3}{value3}

Here \style can define both the background and the border colors.

0

2 Answers 2

4

This is a comment/answer to the comments of Peter Grill's original answer (+1).

The \List macro takes one optional argument, the style that should be used if none is specified (i.e. …,<entry>,…).

I also took the liberty to use the node distance key instead of the hard-coded (0.5*\i cm,0) placement.

Code

\documentclass{article}
\usepackage{tikz}
\usepackage{xstring}
\tikzset{
    raw sort entry/.style={rectangle, thick, draw, node distance=1.5em},
    sort entry black/.style={raw sort entry, black, fill=white},
    sort entry blackgray/.style={raw sort entry, black, fill=gray!25},
    s1/.style={raw sort entry, red, fill=yellow!30},
    s2/.style={raw sort entry, blue, fill=green!20},
    s3/.style={raw sort entry, violet, fill=orange!25}
}
\newcommand*{\List}[2][sort entry black]{%
  \par\noindent%
  \edef\listtoprocess{#2}%
  \def\ListToProcess{}%
  \begin{tikzpicture}[inner sep=2pt, outer sep=0]
    \foreach \content in \listtoprocess{
      \IfSubStr{\content}{/}{% true
        \xdef\ListToProcess{\ListToProcess,\content}
      }{%                      false
        \xdef\ListToProcess{\ListToProcess,#1/\content}
      }
    }
    \StrGobbleLeft{\ListToProcess}{1}[\ListToProcess]% removes the first comma (\listToProcess is empty at the start)
    \foreach [count=\i] \Style/\Value in \ListToProcess {
      \ifnum\i=1\relax
        \node [raw sort entry, \Style] (sortnode\i) {\Value};
      \else
        \node [raw sort entry, right of=sortnode\number\numexpr\i-1\relax, \Style] (sortnode\i) {\Value};
      \fi
    }
  \end{tikzpicture}%
}

\begin{document}
\List{s1/1, 2, s3/3}
\List[sort entry blackgray]{s2/1, s1/2, s1/3, 1, s2/2, s3/3, s2/2, s2/3}
\List[s1]{1,2,/3,/2,3}% /3 and /2 falls back to no explicit \Style, so the resulting style is that from the \node [raw sort entry, …]
\end{document}

Output

enter image description here

3
  • Yes that is what I meant. Also you should define the parameter into a macro, in case it was a macro in the first place -- My answer was edited and have reverted it. Commented Nov 22, 2012 at 6:47
  • @PeterGrill That edit was the reason I noticed the question/answer. I've updated my (your ;)) answer to implement the \edefinition of #2. Commented Nov 22, 2012 at 7:13
  • Very nice collaboration !
    – projetmbc
    Commented Nov 22, 2012 at 8:04
8

To allow for an arbitrary number of parameters I would recommend a slightly different syntax where you provide a comma separated list in the form:

<style>/<value>, <style>/<value>, <style>/<value>, ...

enter image description here

Code:

\documentclass{article}

\usepackage{tikz}

\tikzset{style1/.style={thick, draw=red,fill=yellow!30}}
\tikzset{style2/.style={thick, draw=blue,fill=green!20}}
\tikzset{style3/.style={thick, draw=violet,fill=orange!25}}

\newcommand*{\List}[1]{%
\par\noindent%
\begin{tikzpicture}[inner sep=2pt, outer sep=0]
    \edef\ListToProcess{#1}% Allows for parapamater to be defined via a macro.
    \foreach [count=\i] \Style/\Value in \ListToProcess {
        \node [rectangle,\Style] at (0.5*\i cm,0) {\Value};
    };
\end{tikzpicture}
}

\begin{document}

\List{style1/1, style2/2, style3/3}
\List{style2/1, style1/2, style1/3, style1/1, style2/2, style3/3, style2/2, style2/3}
\List{style3/1, style2/2, style2/3, style1/2, style1/3}
\end{document}
8
  • Superb! I was trying to get something similar, but yours is much better :)
    – cmhughes
    Commented Nov 21, 2012 at 22:39
  • Is there way to use one default value for the style ?
    – projetmbc
    Commented Nov 21, 2012 at 23:03
  • @projetmbc: Yeah there should be, but I can't seems to get it to work right now. Be default \foreach will use the last value if one is not provided. Commented Nov 21, 2012 at 23:26
  • @PeterGrill A not-so-user-friendly way would be to define a default style (e.g. \tikzset{styledefault/.style={thick, draw=black,fill=white}}) and provide styledefault before \Style (i.e. \node […, styledefault, \Style] …) and use it as \List{style1/1, /2, style3/3}. A more sophisticated solution would be to check #1 for entries without / and prepend styledefault/ so one can use \List{style1/1, 2, style3/3}. xstring will be helpful. Commented Nov 22, 2012 at 6:23
  • @Qrrbrbirlbel: I tried that but ran into difficulties. Was thinking of pre-processing the list to complete it (which is what I think the second part of your comment is about). Commented Nov 22, 2012 at 6:25

You must log in to answer this question.

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