Draw a backwards link/pointer in a tree using the forest package
You can give a name
to the nodes and then use regular TikZ drawing commands to connect them. You need to wrap the TikZ commands in braces to protect them from the forest
bracket parser:
\documentclass{article}
\usepackage{forest}
\begin{document}
\begin{forest}
for tree={circle,draw,s sep=0.8cm}
[$\lambda$
[,{edge label={node[midway,left] {B}}},{text=white,fill=black}
[,{edge label={node[midway,left] {A}}}
[,{edge label={node[midway,left] {B}}}
[,name=A2,{edge label={node[midway,left] {A}}},
{text=white,fill=black}]
]
]
]
[,name=A1,{edge label={node[midway,right] {A}}}
[,{edge label={node[midway,right] {B}}},
{text=white,fill=black}
[,{edge label={node[midway,right] {A}}},
{text=white,fill=black}]
]{\draw[->] (A2) .. controls +(right:1) and +(left:1) .. (A1);}
]
]
\end{forest}
\end{document}
Here's an adaptation of Alan Munn's answer which may be of interest if you don't like typing or need to draw lots of trees in this style.
I define the the tree styles labelled tree
and circle tree
for use in the preamble of trees.
labelled tree
activates a style which allows you to specify
<content>:<edge label>
as the node's content and have the edge label automatically positioned to the left or the right.
circle tree
just makes the nodes circles etc.
In addition, inverse
sets the text to white and the fill to black.
Finally, arrow to
is a style which takes three arguments.
arrow to={<first control point>}{<second control point>}{<node to connect to>}
This allows you to specify the connector as an option to the node from which the connection should be drawn. The node to connect to may be specified either using a relative node name (e.g. !r2
in this example) or using a label specified with name
(as in Alan's answer).
This means that we can draw Alan's tree using the following code.
\begin{forest}
labelled tree,
circle tree,
[$\lambda$
[:B, inverse
[:A
[:B
[:A, inverse, arrow to={right:1}{left:1}{!r2}
]
]
]
]
[:A
[:B, inverse
[:A, inverse
]
]
]
]
\end{forest}
More generally,
\begin{forest}
labelled tree,
circle tree,
[$\lambda$
[:B, inverse
[:A
[:B
[:A, inverse, arrow to={right:1}{left:1}{!r2}
]
]
]
]
[:A
[:B, inverse
[:A, inverse
]
]
]
]
\end{forest}
\begin{forest}
labelled tree,
circle tree,
[$\lambda$
[:B, inverse
[:A
[:B
[:A, inverse, arrow to={left:1}{left:1}{!r1}
]
]
]
]
]
\end{forest}
\begin{forest}
labelled tree,
circle tree,
[$\lambda$
[:B, inverse
[:A
[:B
[:A, inverse, arrow to={right:1}{left:1}{!r2}
]
]
]
]
[:A
[:B, inverse
[:A, inverse
]
]
]
[:B
[:A, inverse
[:B
[:A, inverse, arrow to={left:1}{right:1}{!r2}
]
]
]
]
]
\end{forest}
\begin{forest}
labelled tree,
circle tree,
[$\lambda$
[$\omega$
[:B, inverse
[:A
[:B
[:A
[:B, inverse, arrow to={right:1}{left:1}{!uuu2}
]
]
]
[:A
[:B
[:A, inverse, arrow to={right:1}{left:1}{!r12}
]
]
]
]
]
[:A
[:B, inverse
[:A, inverse
]
]
]
[:B
[:A, inverse
[:B
[:A, inverse, arrow to={left:1}{right:1}{!r12}
]
]
]
]
]
]
\end{forest}
produces
Complete code:
\documentclass[border=10pt]{standalone}
\usepackage{forest}
\forestset{
declare boolean register=sloped labels,
not sloped labels,
my edge label/.style={
tempcountc/.option=grow,
if reversed={
tempcountc-/.register=tempcountb,
}{
tempcountc+/.register=tempcountb,
},
if sloped labels={
temptoksa=sloped,
}{
temptoksa=,
},
edge label/.expanded={node [midway, shift=(\foresteregister{tempcountc}:10pt), \foresteregister{temptoksa}] {#1}}
},
labelled tree/.style={
before typesetting nodes={
where={(n_children())>1}{
tempcounta/.pgfmath={int(((n_children())+1)/2)},
if={isodd(n_children())}{
for n/.wrap pgfmath arg={{##1}{calign with current}}{(tempcounta)},
}{},
for nodewalk={
n=1,
filter={current and siblings}{n()<(tempcounta)},
}{
for nodewalk={
c,
while={int(n_children())==1}{
on invalid={fake}{n=1},
}{},
}{
tempcountb'=-90,
split option={content}{:}{content,my edge label},
},
},
for nodewalk={
n'=1,
filter={current and siblings}{n()>=(tempcounta)},
}{
for nodewalk={
c,
while={int(n_children())==1}{
on invalid={fake}{n=1},
}{},
}{
tempcountb'=-270,
split option={content}{:}{content,my edge label},
},
},
}{},
for nodewalk={
fake=r,
while={int(n_children())==1}{
on invalid={fake}{n=1},
}{},
}{
tempcountb'=-270,
split option={content}{:}{content,my edge label},
},
},
},
arrow to/.style n args=3{
tikz+={
\draw [->] () .. controls +(#1) and +(#2) .. (#3);
}
},
inverse/.style={text=white, fill=black},
circle tree/.style={
for tree={
circle,
draw,
s sep=0.8cm,
edge={->},
},
}
}
\begin{document}
\begin{forest}
labelled tree,
circle tree,
[$\lambda$
[:B, inverse
[:A
[:B
[:A, inverse, arrow to={right:1}{left:1}{!r2}
]
]
]
]
[:A
[:B, inverse
[:A, inverse
]
]
]
]
\end{forest}
\begin{forest}
labelled tree,
circle tree,
[$\lambda$
[:B, inverse
[:A
[:B
[:A, inverse, arrow to={left:1}{left:1}{!r1}
]
]
]
]
]
\end{forest}
\begin{forest}
labelled tree,
circle tree,
[$\lambda$
[:B, inverse
[:A
[:B
[:A, inverse, arrow to={right:1}{left:1}{!r2}
]
]
]
]
[:A
[:B, inverse
[:A, inverse
]
]
]
[:B
[:A, inverse
[:B
[:A, inverse, arrow to={left:1}{right:1}{!r2}
]
]
]
]
]
\end{forest}
\begin{forest}
labelled tree,
circle tree,
[$\lambda$
[$\omega$
[:B, inverse
[:A
[:B
[:A
[:B, inverse, arrow to={right:1}{left:1}{!uuu2}
]
]
]
[:A
[:B
[:A, inverse, arrow to={right:1}{left:1}{!r12}
]
]
]
]
]
[:A
[:B, inverse
[:A, inverse
]
]
]
[:B
[:A, inverse
[:B
[:A, inverse, arrow to={left:1}{right:1}{!r12}
]
]
]
]
]
]
\end{forest}
\end{document}