Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am currently trying to typeset a prefix tree (also called a trie). I can make a tree just fine with TiKZ, but I find myself unable to make the prefix tree nodes draw acceptably. I have attached a whiteboard drawing of a prefix tree containing the words "ghost", "green", "tan", "trie", and "trie". I can't seem to work out how to make TiKZ draw that same tree. Any help would be gratefully accepted.

The prefix tree I would like to draw in LaTeX, drawn on my whiteboard

I have tried rectangle split, and that works to divide the node up into an upper and lower part, but how can I subdivide the lower part? Also, how can I make the arrows in the lower part come explicitly from the letter, and not from the surrounding node?

share|improve this question

1 Answer 1

up vote 19 down vote accepted

The real trick here is how to put the outer boxes around the inner nodes. As you may have already discovered, it's not possible to embed a \node inside another \node. It is also a really bad idea to embed one tikzpicture inside another (which might appear to be another solution to this problem. Here's a solution that is based on Mark Everitt's answer to this question tikz: a big box with fixed width containing smaller boxes.

It uses the shapes.multipart library to split the tree nodes, and the fit library to put outer boxes around the tree nodes. The positioning and calc libraries are used to calculate the placement of the outer node text, and the edge from parent path, so that although the tree is built on the inner nodes, the branches actually connect at a point that appears to be the edge of the outer nodes.

Update: Based on this question: How to make tikz multipart node parts have uniform size? I've added some code to make all the inner nodes (both split and single) uniform size.

\documentclass{article}
\usepackage{tikz-qtree}
\usetikzlibrary{fit,backgrounds,shapes.multipart,calc,positioning}
\begin{document}
\tikzset{
    sibling distance=2cm,
    level distance=2.5cm,
    split/.style={draw, 
        rectangle split, rectangle split parts=2,draw,inner
        sep=0pt,rectangle split horizontal,minimum size=3ex,text width=3ex,align=center,rectangle split part align=base},
    boxed/.style={draw,minimum size=3ex,inner sep=0pt,align=center},
    edge from parent/.style={draw, 
        edge from parent path={[->,thick]
        (\tikzparentnode)  -- ($(\tikzchildnode.north) + 25*(0pt,1pt)$) }}
}

\begin{tikzpicture}
\Tree [.\node[split] (M1) {g\nodepart{two}t}; 
                [.\node[split] (M2) {h\nodepart{two}r}; 
                    [.\node[boxed] (M3) {o};
                        [.\node[boxed] (M4) {s};
                            [.\node[boxed] (M5) {t}; 
                                [.\node[boxed] (E1) {};]
                            ]
                        ]
                    ]
                    [.\node[boxed] (M6) {e};
                        [.\node[boxed] (M7) {e};
                            [.\node[boxed] (M8) {n};
                                [.\node[boxed] (E2) {};]
                            ] 
                        ]
                    ]
                ]  
                [.\node[split]  (M9) {a\nodepart{two}r};
                    [.\node[boxed] (M10) {n};
                        [.\node[boxed] (E3) {};]
                    ]
                    [.\node[split] (M11) {e\nodepart{two}i};
                        [.\node[boxed] (M12) {e}; 
                            [.\node[boxed] (E4) {};]
                        ]
                        [.\node[boxed] (M13) {e};
                            [.\node[boxed] (E5) {};]
                        ] 
                    ]
                ]
            ]
\begin{pgfonlayer}{background}
\foreach \x in {1,...,13}{
    \node (A\x)  [above =5pt of M\x] {Middle};
    \node[draw,red,] [fit=(M\x) (A\x) ] {};}
\foreach \x in {1,...,5}{
    \node (B\x)  [above =5pt of E\x] {End};
    \node[draw,red,] [fit=(E\x) (B\x) ] {};}
\end{pgfonlayer}
\end{tikzpicture}
\end{document}

output of code

share|improve this answer
    
But this answer have no squigly arrows! :p (Upvoted, nice answer) –  N3buchadnezzar Jul 1 '12 at 18:07
1  
@N3buchadnezzar I like my trees to have sturdy branches. –  Alan Munn Jul 1 '12 at 19:23
    
This is exactly it! As you intuited, I had tried putting nodes in nodes, and I had tried to see how to make my own node shape class (is class even the right word?). Thank you so much for the help! –  Peter Boothe Jul 2 '12 at 14:52

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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