The following image shows a recursive H-Layout tree.
It is called H-Layout because of its H unit consisting of 7 nodes.
My problem is:
How to draw such tree in a recursive manner instead of drawing each node explicitly?
recursiontikz-pgftikz-trees
The following image shows a recursive H-Layout tree.
It is called H-Layout because of its H unit consisting of 7 nodes.
My problem is:
How to draw such tree in a recursive manner instead of drawing each node explicitly?
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}
Can I offer you a forest
?
\documentclass[tikz]{standalone}
\usepackage{forest}
\begin{document}
\begin{forest}
Stern Brocot/.style n args={5}{%
content=$\frac{\number\numexpr#1+#3\relax}{\number\numexpr#2+#4\relax}$,
if={#5>0}{% true
append={[,Stern Brocot={#1}{#2}{#1+#3}{#2+#4}{#5-1}]},
append={[,Stern Brocot={#1+#3}{#2+#4}{#3}{#4}{#5-1}]}
}{}}% false (empty)
[,Stern Brocot={0}{1}{1}{0}{3}]
\end{forest}
\end{document}
\documentclass[tikz]{standalone}
\usepackage{forest}
\makeatletter
\pgfmathdeclarefunction{strrepeat}{2}{%
\begingroup\pgfmathint{#2}\pgfmath@count\pgfmathresult
\let\pgfmathresult\pgfutil@empty
\pgfutil@loop\ifnum\pgfmath@count>0\relax
\expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult#1}%
\advance\pgfmath@count-1\relax
\pgfutil@repeat\pgfmath@smuggleone\pgfmathresult\endgroup}
\makeatother
\tikzset{
Stern Brocot at/.style={at/.wrap 2 pgfmath args={([rotate around=180:(!##1)] !##22)}
{strrepeat("#1",\SBLevel)}{strrepeat("#1",\SBLevel-1)}},
Stern Brocot at*/.style n args={3}{
at/.wrap pgfmath arg={(!##1-|SB@#3)}{strrepeat("#1",#2)},
/forest/if={#2<\SBLevel}{append after command=
(\tikzlastnode) edge[densely dotted] (SB@#3@\the\numexpr\SBLLoop+1\relax)}{}}}
\forestset{
Stern Brocot*/.style n args={2}{
content=$\frac{#1}{#2}$,
edge=densely dotted,
if={level()<\SBLevel}{append={[,Stern Brocot*={#1}{#2}]}}{}},
Stern Brocot/.style n args={5}{
/utils/exec=\edef\SBLevel{#5},@Stern Brocot={#1}{#2}{#3}{#4}},
@Stern Brocot/.style n args={4}{
/utils/exec=\edef\SBTop {\number\numexpr#1+#3\relax}% eTeX instead of PGFmath
\edef\SBBottom{\number\numexpr#2+#4\relax},
content/.expanded=$\frac{\SBTop}{\SBBottom}$,
if/.expanded={level()<\SBLevel}{% true
append={[,@Stern Brocot={#1}{#2}{\SBTop}{\SBBottom}]},
append={[,Stern Brocot*={\SBTop}{\SBBottom}]},
append={[,@Stern Brocot={\SBTop}{\SBBottom}{#3}{#4}]}
}{}}}% false (empty)
\begin{document}
\begin{forest}[,Stern Brocot={0}{1}{1}{0}{3}]
\coordinate[Stern Brocot at=1] (SB@left) coordinate[Stern Brocot at=3] (SB@right);
\foreach \SBLLoop in {\SBLevel, ..., 0}
\path node[Stern Brocot at*={1}{\SBLLoop}{left}] (SB@left@\SBLLoop) {$\frac01$}
node[Stern Brocot at*={3}{\SBLLoop}{right}] (SB@right@\SBLLoop) {$\frac10$};
\end{forest}
\end{document}
Best Answer
Code A (preferred)
Code B
Output