9

I know how to create a multipart node in TikZ using \nodepart, and I know how I can draw lines from these nodeparts to hook them up to other nodes:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\tikzset{
    bnode/.style = {                                                     
        draw,
        rectangle split,
        rectangle split horizontal,
        rectangle split parts=4
    }
}
\begin{document}
\begin{tikzpicture}
\node[bnode]
   (root)
   {      \nodepart{one}
      $12$ \nodepart{two}
      $15$ \nodepart{three}
      $20$ \nodepart{four}
      $\times$};

\draw[->]
    (root.south west) -- +(-4,-1)
    node[bnode, anchor=north]
        (childnode)
        {      \nodepart{one}
            $3$ \nodepart{two}
            $9$ \nodepart{three}
            $10$ \nodepart{four}
            $12$};                           

\draw[->]
    (root.one split south) -- +(-2,-1)
    node[bnode, anchor=north]
        (childnode)
        {      \nodepart{one}
            $13$ \nodepart{two}
            $14$ \nodepart{three}
            $15$ \nodepart{four}
            $\times$};

\draw[->]
    (root.two split south) -- +(0,-1)
    node[bnode, anchor=north]
        (childnode)
        {      \nodepart{one}
            $17$ \nodepart{two}
            $18$ \nodepart{three}
            $\times$ \nodepart{four}
            $\times$};

\draw[->]
    (root.three split south) -- +(2,-1)
    node[bnode, anchor=north]
        (childnode)
        {      \nodepart{one}
            $21$ \nodepart{two}
            $29$ \nodepart{three}
            $\times$ \nodepart{four}
            $\times$};


\end{tikzpicture}
\end{document}

Renders:

enter image description here

Even in this simple example I had to calculate the correct location of the child nodes because they are overlapping. Imagine adding another level to the tree. These calculations would become very tedious.

I know TikZ has some nice tree syntax to easily draw trees, but I don't immediatly see how it applies here. Is there a way to use TikZ' child syntax to work with multipart nodes so that I don't have to worry about the spacing and location of their child nodes.

To clarify: every part of a multipart node should be able to have it's own child proper, and the children are multipart nodes themselves, which again can have multiple children (one for each nodepart).

3 Answers 3

13

The probem stems from the fact that the a' is wider than just a. So, you can set the text width=1.0em, align=center which ensures that each of the nodes are of the same width:

enter image description here

Code:

\documentclass[border=2pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\tikzset{
    bnode/.style = {   
        text width=1.0em, align=center,                                           
        draw,
        rectangle split,
        rectangle split horizontal,
        rectangle split parts=4
    }
}
\begin{document}
\begin{tikzpicture}
    \node[bnode]
       (root)
       {      \nodepart{one}
          $a$ \nodepart{two}
          $b$ \nodepart{three}
          $c$ \nodepart{four}
          $d$};

    \draw (root.one south) -- +(0,-1) node[draw, anchor=north](q) {$a'$};
    \draw (root.two south) -- +(0,-1) node[draw, anchor=north](q) {$b'$};
\end{tikzpicture}
\end{document}
3
  • Perhaps I wasn't clear enough about this. The a' and b' nodes are in reality themselves also multipart nodes, so they will be wider also. My question was: is there a way to automation the placing and connecting of these bushy tree structures.
    – romeovs
    Jun 17, 2014 at 11:28
  • @romeovs: I'd suggest you update the question then and include code that shows the problem better. Not sure if there is a generic solution that will work in all cases, so if we have an actual example that reproduces the problem then perhaps a solution can be found that works for you. Jun 17, 2014 at 19:46
  • yes I elaborated the MWE!
    – romeovs
    Jun 18, 2014 at 7:58
7

After almost five years ...

With use the calc, chain and positioning library the distance between node is simple to determine. Beside this, code is also short and clear:

\documentclass[tikz, margin=3mm]{standalone}
\usetikzlibrary{arrows.meta,
                calc, chains,
                positioning,
                shapes.multipart}

\begin{document}
    \begin{tikzpicture}[
  node distance = 13mm and 1mm,
    start chain = A going right,
mpn/.style args = {#1/#2/#3/#4}{draw,
    rectangle split, rectangle split horizontal,
    rectangle split parts=4,
    on chain=A,
    node contents={ \nodepart{one}    $#1$
                    \nodepart{two}    $#2$
                    \nodepart{three}  $#3$
                    \nodepart{four}   $#4$}
                                },
                        ]
\node[mpn=3/9/10/12];
\node[mpn=13/14/15/\times];
\node[mpn=17/18/\times/\times];
\node[mpn=21/29/\times/\times];
%
\node[mpn=12/15/20/\times,
      above=of $(A-1.north west)!0.5!(A-4.north east)$];
\foreach \i in {1,...,4}
\draw[-Stealth, semithick, shorten >=1mm, shorten <=1mm]
    (A-5) -- (A-\i.north);
    \end{tikzpicture}
\end{document}

enter image description here

This two level tree can be easy extend to more level. The lower level should be designed similar as in above MWE, higher level are just repetition of the top layer from above MWE.

addendum: with use of the forest package you can design a tree as you wish:

    \documentclass[tikz, margin=3mm]{standalone}
    \usetikzlibrary{arrows.meta,
                    shapes.multipart}
    \usepackage{forest}
    \newcommand\mpnc[4]{\nodepart{one}      $#1$
                        \nodepart{two}      $#2$                    
                        \nodepart{three}    $#3$
                        \nodepart{four}     $#4$}

    \begin{document}
        \begin{forest}
    for tree = {
        rectangle split,
        rectangle split horizontal,
        rectangle split parts=4,
        draw,
        %
        parent anchor=south,
        child anchor=north,
        edge = {-Stealth, semithick, shorten >=1mm, shorten <=1mm},
        l sep=12mm,
        s sep=1mm,
                }
    [{\mpnc{12}{15}{20}{\times}}
        [{\mpnc{3}{9}{12}{\times}}]
        [{\mpnc{13}{14}{15}{\times}}]
        [{\mpnc{17}{18}{\times}{\times}}]
        [{\mpnc{21}{29}{\times}{\times}}]
    ]
        \end{forest}
    \end{document}

enter image description here

0

Unfortunately its not a real answer. However, if it's not too late, I'd like to share a solution of mine.

It's not a very good one and can be improved, but I hope it can help you somehow. :)

Edit: \tikzstyle replaced by \tikset.

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}

\usepackage{tikz}
\usetikzlibrary{arrows, shapes, trees, calc, positioning}
\tikzset{
    key/.style = {
        circle,
        fill = white,
        dotted,
        thick,
        draw,
    },
    vazio/.style = {
        draw = none,
        fill = none,
    },
    no/.style = {
        rectangle split,
        rectangle split horizontal,
        rectangle split parts = #1,
        rectangle split draw splits = false,
        rounded corners,
        fill = black!15,
        draw = black!85,
        thick,
        anchor = center,
        minimum height = 1.8em,
    },
    no b/.style = {
        rectangle split,
        rectangle split horizontal,
        rectangle split parts = #1,
        rectangle split empty part width = 1.3ex,
        rectangle split draw splits = false,
        rounded corners,
        fill = black!15,
        draw = black!85,
        thick,
        anchor = center,
        minimum height = 1.8em,
    }, 
    edge from parent/.style = {
        thick,
        -latex,
        draw = black,
    },
    child/.style = {
        edge from parent path = {(\tikzparentnode.west)
            ++(0.06cm+#1*0.65cm, -0.18cm) -- (\tikzchildnode)},
    },
    nil/.style = {
        edge from parent = {thick, -square, draw = gray},
    },
}

\begin{document}

\begin{tikzpicture}[scale = 0.65, transform shape]
    \tikzstyle{every node} = [no b]
    \tikzstyle{level 1} = [sibling distance = 12cm]
    \tikzstyle{level 2} = [sibling distance = 3cm]
    \node (tree) {42}
        child[child = 0] {node {19 \nodepart{two} 33}
            child[child = 0] {node {10 \nodepart{two} 15 \nodepart{three} 16
                \nodepart{four} 18}}
            child[child = 1] {node {22 \nodepart{two} 27 \nodepart{three} 29}}
            child[child = 2] {node {35 \nodepart{two} 40 \nodepart{three} 41}}
        }
        child[child = 1] {node {61 \nodepart{two} 74 \nodepart{three} 85 
                \nodepart{four} 95}
            child[child = 0] {node {47 \nodepart{two} 49 \nodepart{three} 53}}
            child[child = 1] {node {65 \nodepart{two} 68 \nodepart{three} 72}}
            child[child = 2] {node {77 \nodepart{two} 81}}
            child[child = 3] {node {88 \nodepart{two} 90 \nodepart{three} 93
                \nodepart{four} 94}}
            child[child = 4] {node {97 \nodepart{two} 98}}
        }
    ;
    \draw [latex-, thick] (tree) -- ++ (0, 1);
\end{tikzpicture}

\end{document}
2
  • Please do not use \tikzstyle!!
    – user156344
    May 20, 2019 at 15:24
  • Thanks, @JouleV. Old code, many corrections needed... Unfortunately, no time for it so far.
    – Jander
    May 21, 2019 at 16:40

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.