
Forest パッケージを使用して、赤黒ツリーを作成しようとしています。プレゼンテーションのある時点で、赤であるが親が黒であるノード間の線を短くする必要があります。
\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}
以下のコードによって生成された出力を確認できます。
このステップの後、私は次のようなことをやろうとしています。
図のスタイルの違いは無視してください。赤と黒のノード間の線の長さを短くしようとしているだけです。
答え1
例として、あなたがコード化したツリーを使用していることに注意してください。4 番目のツリーには赤いノードがないため、質問は赤い子と黒い親の間の距離を調整することに特化しているため、この場合は何もする必要はありません。
したがって、質問は基本的に、1 つのツリーを 3 つの異なる方法でフォーマットする方法を尋ねています。次のコードでは、@+\rbtree
変更されたスタイルなどで整理されたツリーの括弧仕様に展開されます。
\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}
このコードは距離を短くしますが、とにデフォルト以外の値を使用するためs adjust
、l short
赤い子要素は互いに重なり合い、黒い親要素の下に重なります。はnot distinct
ドロップ シャドウをオフにし、ノードの分離を促すためのコードを無効にし、ツリーの描画順序を変更します。通常、ツリーは上から下に描画されますが、ここではそのようにしたくないため、tree children-first
代わりにを使用してツリーを下から上に描画します。これにより、子要素は親要素と重なるのではなく、親要素の下に重なります。
\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}
の使用は、\rbtree
純粋に利便性のためであることに注意してください。複数のツリーで同じコンテンツが必要な場合を除き、これを無視して、通常の方法でツリーを指定する必要があります。最初の 3 つのツリーの仕様が同一であるため、重複を回避するだけです。