
透過使用 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
請注意,我使用您編碼的樹作為範例。第四棵樹沒有紅色節點,因此,由於問題具體涉及調整紅色子節點和黑色父節點之間的距離,因此在這種情況下無需執行任何操作。
所以這個問題基本上是問如何以三種不同的方式格式化一棵樹。在下面的程式碼中,@+\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
純粹是為了方便。除非您需要在多個樹中使用相同的內容,否則您應該忽略這一點並以通常的方式指定您的樹。它只是避免了重複,因為前三棵樹具有相同的規格。