
Mithilfe des Forest-Pakets versuche ich, einen rot-schwarzen Baum zu erstellen. An einer Stelle meiner Präsentation muss ich die Linien zwischen den Knoten kürzen, die rot sind, deren Eltern jedoch schwarz sind.
\documentclass{article}
\usepackage{graphicx}
\usepackage{forest}
\begin{document}
\begin{forest}
for tree={circle, draw, s sep=15pt, l sep=5pt, font=\tiny\color{white}\bfseries, minimum size=15pt},
[, fill=black!80
[, fill=black!80
[, draw=none]
[, draw=none]
]
[, fill=red!80
[, fill=black!80
[, fill=red!80
[, draw=none]
[, draw=none]
]
[, fill=red!80
[, draw=none]
[, draw=none]
]
]
[, fill=black!80
[, draw=none]
[, fill=red!80
[, draw=none]
[, draw=none]
]
]
]
]
\end{forest}
\end{document}
Sie können die vom Code generierte Ausgabe unten sehen.
Nach diesem Schritt versuche ich, so etwas zu machen.
Bitte ignorieren Sie den Stilunterschied zwischen den Abbildungen. Ich versuche nur, die Länge der Linien zwischen den rot-schwarzen Knoten zu verkürzen.
Antwort1
Beachten Sie, dass ich den von Ihnen codierten Baum als Beispiel verwendet habe. Der vierte Baum hat keine roten Knoten. Da es in der Frage speziell um die Anpassung der Abstände zwischen roten Kindern und schwarzen Eltern geht, muss in diesem Fall nichts getan werden.
Die Frage lautet also im Wesentlichen, wie ein Baum auf drei verschiedene Arten formatiert werden kann. Im folgenden Code @+\rbtree
wird die Klammerspezifikation Ihres Baums erweitert, indem einige Aufräumarbeiten mit geänderten Stilen und dergleichen vorgenommen werden.
\begin{forest}
red black,
@+\rbtree
\end{forest}
Dies führt zu dem in Ihrer Frage gezeigten Ergebnis mit geringfügigen Änderungen, die es Ihrem Wunsch etwas näher bringen. Dies ist die Basislinie/der Ausgangspunkt.
\begin{forest}
red black,
squash,
@+\rbtree
\end{forest}
Dies stellt eine Annäherung an den nächsten Baum dar. Rote Knoten werden näher an schwarze Eltern verschoben, sie dürfen sich jedoch nicht überlappen.
\begin{forest}
red black,
squash,
not distinct,
s adjust'=4,
l short'=10pt,
@+\rbtree
\end{forest}
Dieser Code verkürzt die Abstände, verwendet aber nicht standardmäßige Werte für s adjust
und l short
so überlappen sich rote Kinder gegenseitig und unterlappen ihre schwarzen Eltern. not distinct
schaltet Schlagschatten aus, deaktiviert Code, der zur Förderung der Knotentrennung verwendet wird, und ändert die Reihenfolge, in der der Baum gezeichnet wird. Normalerweise werden Bäume von oben nach unten gezeichnet, aber das wollen wir hier nicht, also zeichnen wir tree children-first
den Baum stattdessen von unten nach oben. Dadurch überlappen sich die Kinder unter den Eltern, anstatt sie zu überlappen.
\documentclass[tikz,border=5pt]{standalone}
\usepackage{forest}
\usetikzlibrary{shadows}
% ateb : https://tex.stackexchange.com/a/707076/ addaswyd o gwestiwn İbrahim Uğur ABA: https://tex.stackexchange.com/q/706871/
\forestset{%
declare boolean={red node}{0},
declare boolean={black node}{0},
declare boolean={squashed}{0},
declare boolean register={squash},
declare boolean register={distinct},
not squash,
distinct,
declare dimen register={l short},
declare count register={s adjust},
l short'=15pt,
s adjust'=5,
red black/.style={%
for tree={%
fit=band,
circle,
draw,
s sep'=15pt,
l'=5pt,
l sep'=5pt,
edge+=thick,
if n children=0{%
inner sep=.5pt,
fill,
before computing xy={l'=12pt},
}{%
text=white,
font=\tiny\sffamily\bfseries,
minimum size=15pt,
},
},
before typesetting nodes={%
if squash={%
for descendants={%
if={ > OO& {red node}{!u.black node} }{%
before computing xy={%
l/.register=l short,
if={ > OOw+P< {n} {!u.n children}{(##1+1)/2} }{%
s/.process={ ORw2+Pw+d {n}{s adjust}{-##2*##1}{##1pt} }
}{%
s/.process={ ORw2+Pw+d {n}{s adjust}{##2*##1}{##1pt} }
},
},
}{},
},
if distinct={%
where black node={%
tempcounta'=0,
if nodewalk empty={filter={children}{>O{red node}}}{}{%
for nodewalk={filter={children}{>O{red node}}}{%
if={ > O_ > {n}{1} }{%
if={ > O {!p.red node} }{%
insert before={[,phantom]}
}{},
}{},
},
},
}{},
}{%
/tikz/circular drop shadow/.style={},
draw tree processing order/.nodewalk style=tree children-first,
},
}{},
},
},
red one/.style={fill=red,circular drop shadow,red node},
black one/.style={fill=black,circular drop shadow,black node},
}
\bracketset{action character=@}
\NewDocumentCommand \rbtree {}{%
[, black one
[, black one
[]
[]
]
[, red one
[, black one
[, red one
[]
[]
]
[, red one
[]
[]
]
]
[, black one
[]
[, red one
[]
[]
]
]
]
]%
}
\begin{document}
\begin{forest}
red black,
@+\rbtree
\end{forest}
\begin{forest}
red black,
squash,
@+\rbtree
\end{forest}
\begin{forest}
red black,
squash,
not distinct,
s adjust'=4,
l short'=10pt,
@+\rbtree
\end{forest}
\end{document}
Beachten Sie, dass die Verwendung von \rbtree
nur aus praktischen Gründen erfolgt. Sofern Sie nicht denselben Inhalt in mehreren Bäumen benötigen, sollten Sie dies ignorieren und Ihre Bäume auf die übliche Weise angeben. Dadurch wird lediglich eine Duplizierung vermieden, da die ersten drei Bäume identische Spezifikationen haben.