3

I want to draw a binary tree like the one in the picture below. Unfortunately, I do not have any clue, whatsoever, on how to draw two trees from top and bottom to match their leaves. Any help would be greatly appreciated.

enter image description here

  • 2
    Welcome to TeX.SX! Do you have some code to share about your attempts? – egreg Nov 24 '14 at 16:50
  • @ergreg Thank you! But I only have the code for top tree using tikzpicture, which i think won't help anyone here. In the meantime, I will try to study the code provided by Mr. Medina. Thank you again. – kailashbuki Nov 24 '14 at 19:14
5

One option:

enter image description here

The code:

\documentclass{article}
\usepackage{forest}
\usetikzlibrary{positioning,arrows.meta}

\newsavebox\Downtree
\newsavebox\Uptree

\tikzset{
  nleft/.style={text width=15pt,midway,left,font=\strut\scriptsize},
  nright/.style={text width=15pt,midway,right,font=\strut\scriptsize},
  }

\savebox\Downtree{\begin{forest}
for tree={
  s sep=25pt,
  l sep=20pt,
  where n children=0{inner ysep=0pt}{draw,circle},
  edge={->,>=latex}
}
[Y3
  [Y2,edge label={node[nleft]{yes}}
    [,edge label={node[nleft]{yes}}]
    [,edge label={node[nright]{no}}]
  ]
  [Y1,edge label={node[nright]{no}}
    [,edge label={node[nleft]{yes}}]
    [,edge label={node[nright]{no}}]
  ]
]
\end{forest}%
}
\savebox\Uptree{\begin{forest}
for tree={
  grow'=north,
  s sep=25pt,
  l sep=20pt,
  where n children=0{inner ysep=0pt}{draw,circle},
  edge={->,>=latex}
}
[X3
  [X4,edge label={node[nleft]{no}}
    [,edge label={node[nleft]{no}}]
    [,edge label={node[nright]{yes}}]
  ]
  [X1,edge label={node[nright]{yes}}
    [,edge label={node[nleft]{no}}]
    [,edge label={node[nright]{yes}}]
  ]
]
\end{forest}%
}

\begin{document}

\begin{tikzpicture}[>={Latex[open]}]
\node[inner sep=0pt] (Down) {\usebox\Downtree};
\coordinate (aux);
\node[inner sep=0pt,below=0pt of Down] (Up) {\usebox\Uptree};
\begin{scope}[red,->]
\draw
  ([xshift=-15pt,yshift=-10pt]Down.north) to[bend right] (Down.south west);
\draw
  ([xshift=-15pt,yshift=10pt]Up.south) to[bend left] (Up.north west);
\end{scope}
\begin{scope}[blue,->]
\draw
  ([xshift=15pt,yshift=-10pt]Down.north) to[bend left] (Down.south east);
\draw
  ([xshift=15pt,yshift=10pt]Up.south) to[bend right] (Up.north east);
\end{scope}
\begin{scope}[green,<->]
\draw
  ([xshift=-2pt]Down.south) 
  .. controls ++(-10pt,2cm) and ++(10pt,2cm) .. 
  ([xshift=2pt]Down.south);
\draw
  ([xshift=-2pt]Up.north) 
  .. controls ++(-10pt,-2cm) and ++(10pt,-2cm) .. 
  ([xshift=2pt]Up.north);
\end{scope}

\end{tikzpicture}

\end{document}

I used the forest package to build two separate trees; one of then growing downwards, and the other one, growing upwards. Each tree is first boxed and then the boxes are placed inside \nodes in a tikzpicture to easily draw the red and green arrows.

  • Thank you @Gonzalo. It works like a charm and the code is also clear to understand. I see that there is a big space between the two trees. If I just change the "below" property of downtree node to negative values, I can squeeze the space, but suddenly all the arrows start to mess up. I appreciate++ your extra help in advanced. :) – kailashbuki Nov 24 '14 at 22:42
  • @kailashbuki You're welcome! I changed the code; specifically, I changed where n children=0{}{draw,circle} to where n children=0{inner ysep=0pt}{draw,circle} so now leaves won't take that much vertical space; in this way, the separation between the two trees decreases and now the below key allows better controlling of the vertical spacing; I also simplified the code for the edge labels using some styles. Let me know if this produces the desired result. – Gonzalo Medina Nov 24 '14 at 23:01
2

Although you want to draw trees, there's no need to use Tikz trees, tikz-qtree, forest, ... for drawing them. A matrix like in next code or just correctly positioned nodes can do the same.

And next code doesn't insert a tikzpicture inside another tikzpicture which sometimes is not recommended.

\documentclass[tikz,border=2mm]{standalone}

\usetikzlibrary{matrix, arrows.meta}

\begin{document}
\begin{tikzpicture}[>=latex]
\matrix (A) [matrix of nodes, nodes={circle,draw},
             row 3/.style={nodes={draw=none, inner sep=0pt},nodes in empty cells},
             row sep=.75cm, column sep=3mm]
{
&[4mm]&&&Y3&&&&[4mm]\\
&&Y2&&&&Y1&&\\
&&&&&&&&\\
&&X4&&&&X1&&\\
&&&&X3&&&&\\
};
\draw[->] (A-1-5)--  node[above left]{yes} (A-2-3);
\draw[->] (A-1-5)-- node[above right]{no} (A-2-7) ;
\draw[->] (A-2-3)--  node[above left]{yes} (A-3-2);
\draw[->] (A-2-3)-- node[above right]{no} (A-3-4) ;
\draw[->] (A-2-7)--  node[above left]{yes} (A-3-6);
\draw[->] (A-2-7)-- node[above right]{no} (A-3-8) ;

\draw[->] (A-5-5)--  node[below left]{no} (A-4-3);
\draw[->] (A-5-5)-- node[below right]{yes} (A-4-7) ;
\draw[->] (A-4-3)--  node[below left]{no} (A-3-2);
\draw[->] (A-4-3)-- node[below right]{yes} (A-3-4) ;
\draw[->] (A-4-7)--  node[below left]{no} (A-3-6);
\draw[->] (A-4-7)-- node[below right]{yes} (A-3-8) ;

\draw[red,->, >={Latex[open]},shorten <=3mm] (A-1-5.north) to[out=180,in=90] (A-3-1);
\draw[red,->, >={Latex[open]},shorten <=3mm] (A-5-5.south) to[out=180,in=-90] (A-3-1);
\draw[blue,->, >={Latex[open]},shorten <=3mm] (A-1-5.north) to[out=0,in=90] (A-3-9);
\draw[blue,->, >={Latex[open]},shorten <=3mm] (A-5-5.south) to[out=0,in=-90] (A-3-9);

\draw[green,<->, >={Latex[open]},shorten <=1mm, shorten >=1mm] (A-3-5) to[loop above,min distance=2cm] (A-3-5);
\draw[green,<->, >={Latex[open]},shorten <=1mm, shorten >=1mm] (A-3-5) to[loop below,min distance=2cm] (A-3-5);

\end{tikzpicture}
\end{document}

enter image description here

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.