2

I'm trying to draw a binary tree using tikz. I use shift option to define the relative position of child nodes. But as the tree grows, the nodes start to overlap if I use a fixed shift. I'm able to get around this by manually specifying the location of children nodes. But is there a better way to do it?

\documentclass{article} \usepackage{tikz} \usetikzlibrary{shapes.geometric,arrows,fit,matrix,positioning} \tikzset { treenode/.style = {circle, draw=black, align=center, minimum size=1cm}, subtree/.style = {isosceles triangle, draw=black, align=center, minimum height=0.5cm, minimum width=0.5cm, shape border rotate=90, anchor=north}, process/.style={rectangle, minimum width=2cm, minimum height=1cm, align=center, text width=2cm, draw}, connector/.style={circle, minimum size=1cm, align=center, text width=0.5cm, draw}, arrow/.style={thick, ->, >=stealth} } \usepackage{circuitikz} \begin{document} \begin{tikzpicture} \newcommand\xShift{1.5} \newcommand\yShift{1} \node(x) [treenode] at (0, 0) {100}; \node(xl) [treenode] at ([shift=({-\xShift,-\yShift})]x) {50}; \node(xr) [treenode] at ([shift=({\xShift,-\yShift})]x) {200}; \node(xll) [treenode] at ([shift=({-\xShift,-\yShift})]xl) {25}; \node(xlr) [treenode] at ([shift=({\xShift,-\yShift})]xl) {70}; \node(xlll) [ground] at ([shift=({-\xShift,-\yShift})]xll) {}; \node(xllr) [subtree] at ([shift=({\xShift,-\yShift})]xll) {}; \node(xlrl) [treenode] at ([shift=({-\xShift,-\yShift})]xlr) {60}; \node(xlrr) [subtree] at ([shift=({\xShift,-\yShift})]xlr) {}; \draw[->] (x) -- (xl); \draw[->] (x) -- (xr); \draw[->] (xl) -- (xll); \draw[->] (xl) -- (xlr); \draw[->] (xll) -- (xlll); \draw[->] (xll) -- (xllr.north); \draw[->] (xlr) -- (xlrl); \draw[->] (xlr) -- (xlrr.north); \end{tikzpicture} \end{document} 

enter image description here

Related question Draw a binary tree using tikz

2
  • Use graphdrawing library and run with lualatex Commented Nov 3, 2014 at 21:36
  • thank you. I tried using it. But since I have three different shapes, it doesn't come out clean. For example, to connect 25 and its right subtree which is a triangle, I'm not able to specify that the arrow should be on the north of the triangle. Commented Nov 3, 2014 at 22:08

1 Answer 1

2

You might try using a matrix of nodes:

\documentclass[tikz,border=5pt]{standalone} \usetikzlibrary{shapes.geometric,matrix} \tikzset { treenode/.style = {circle, draw=black, align=center, text centered, minimum size=1cm}, subtree/.style = {isosceles triangle, draw=black, align=center, minimum height=0.5cm, minimum width=0.5cm, shape border rotate=90}, phantom/.style = {draw=none, minimum size=0pt, inner sep=0pt, outer sep=0pt}, } \usepackage{circuitikz} \begin{document} \begin{tikzpicture} \matrix (mat) [matrix of nodes, nodes={treenode}] { &[5mm] &[5mm] &[5mm] 100 &[5mm] \\[5mm] & & 50 & & 200 \\[5mm] & 25 & & 70 & \\[5mm] |[phantom]| {} & & 60 & & |[subtree]| {} \\ & & |[subtree]| {} & &\\ }; \node [ground] at (mat-4-1) {}; \begin{scope}[draw, ->] \draw (mat-1-4) -- (mat-2-3); \draw (mat-1-4) -- (mat-2-5); \draw (mat-2-3) -- (mat-3-2); \draw (mat-3-2) -- (mat-4-3); \draw (mat-2-3) -- (mat-3-4); \draw (mat-3-4) -- (mat-4-3); \draw (mat-3-4) -- (mat-4-5.north); \draw (mat-3-2) -- (mat-4-1.north); \end{scope} \end{tikzpicture} \end{document} 

nodes

EDIT

In response to the correction in the comment: in this case you could just adjust the matrix accordingly. However, I would probably draw a tree in this case instead. For example:

\documentclass[tikz,border=5pt]{standalone} \usetikzlibrary{shapes.geometric} \usepackage{forest} \usepackage{circuitikz} \begin{document} \tikzset{/forest, subtree/.style={isosceles triangle, draw=black, align=center, minimum height=0.5cm, minimum width=0.5cm, shape border rotate=90, child anchor=north, anchor=north, tier=terminus}, terminus/.style={draw=none, inner sep=0pt, outer sep=0pt, minimum height=0pt, minimum width=0pt, tier=terminus}, } \begin{forest} for tree={ edge path={ \noexpand\path [->, \forestoption{edge}] (!u.parent anchor) -- (.child anchor) \forestoption{edge label}; }, calign=fixed edge angles, calign angle=45, circle, draw=black, align=center, text centered, minimum size=10mm, } [100 [50 [25 [, terminus, name=ground here] [, subtree] ] [70 [60] [, subtree] ] ] [200 ] ] \node [ground] at (ground here) {}; \end{forest} \end{document} 

tree

2
  • I apologize for being not clear. The right child of 25 is a subtree and the left child of 70 is a node with value 60. I do not want them to overlap. Commented Nov 3, 2014 at 23:11
  • 1
    @arunmoezhi Hmm... yes, that would have been easier. See my update. The revised question is more straightforward: I'd assumed that the problem was needing nodes with multiple parents. If you don't need that, a tree is the simplest solution, I think. Commented Nov 3, 2014 at 23:57

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.