Jak narysować diagram drzewa, na którym liście są połączone ze zbieżnymi gałęziami?

Aug 16 2020
\documentclass{article}
\usepackage{fullpage}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{arrows,shapes,positioning,shadows,trees}
\usetikzlibrary{arrows.meta}
\usepackage{mdframed}
\usepackage{boxedminipage}
\usepackage{forest}

\begin{document}

\begin{forest}
% Styling
for tree={
align=center,
parent anchor=south,
child anchor=north,
edge={thick, -{Stealth[]}},
l sep+=10pt,
edge path={
\noexpand\path [draw, \forestoption{edge}] (!u.parent anchor) -- +(0,-10pt) -| (.child anchor)\forestoption{edge label};
},
if level=0{
inner xsep=-15pt,
tikz={\draw [thick] (.south east) -- (.south west);}
}{}
}
%
[Alphabet
[a
[b]
[c] ]
[b
[d]
[e] ]
]
\end{forest}

\end{document}

Jak bym był w stanie połączyć wszystkie gałęzie w sposób pokazany poniżej na szkicu

Odpowiedzi

3 AndréC Aug 16 2020 at 16:29

Aktualizacja 2: Strzałki między węzłami ze specyfikacją nodewalk

Wszystkie dodatkowe strzałki (nie zbudowane natywnie przez las), które łączą dwa węzły, są umieszczane w drzewie za pomocą krótkiej składni spaceru po węzłach . To bez nazywania węzłów jak poprzednio (ćwiczenie w stylu rzeczywistym) . Aby umożliwić wizualizację tych strzałek, pokolorowałem je na czerwono .

Cytuję instrukcję:

Nodewalk to zwięzły sposób wyrażania relacji węzłów. Jest to po prostu ciąg kroków, które są reprezentowane przez pojedyncze znaki, gdzie: u oznacza węzeł macierzysty (w górę); p dla poprzedniego rodzeństwa; n dla następnego rodzeństwa; s o o rodzeństwa (użyteczne tylko w drzewo binarne); 1 , 2 ,. . . 9 dla pierwszego, drugiego,. . . dziewiąte dziecko; l, ostatnie dziecko itp. Pełna specyfikacja - patrz rozdział 3.8.7 .

\documentclass[border=5mm]{standalone}
\usepackage{forest}
\usetikzlibrary{arrows.meta}
\useforestlibrary{linguistics}

\begin{document}
\begin{forest}
% Styling
for tree={
    align=center,
    parent anchor=south,
    child anchor=north,
    edge={thick, -{Stealth[]}},
    l sep+=10pt,
    edge path={\noexpand\path [draw, \forestoption{edge}] (!u.parent anchor) -- +(0,-10pt) -| (.child anchor)\forestoption{edge label};
},
if level=0{inner xsep=-15pt,tikz={\draw [thick] (.south east) -- (.south west);}
}{}
}
%
[Alphabet
    [a
        [b]
        [c,s sep=10,
        [f,s sep=30,
            [,phantom]
            [z,edge={white}]
                {\draw[thick,red,-{Stealth[]}] (!rllN.south east) -- +(0,-10pt) -| (!c); %<-- arrow from g to z
                \draw[thick,red] (!uss.south west) -- +(0,-10pt) -| (!c) ;%<-- arrow from f to z
           }
        ]{\draw[thick,red,shorten >=3pt] (!us.south) -- +(0,-10pt) -| (!c) ;}%<-- arrow from b to f
        [,phantom]          
        ] 
    ]
    [b
        [d]
        [e,s sep=9
            [g]{\draw[thick,red,shorten >=3pt] (!us.south) -- +(0,-10pt) -| (!c) ;}%<-- arrow from d to g
            [,phantom]         
        ] 
    ]
]
\end{forest}

\end{document}

W odpowiedzi na aktualizację

Dużo majsterkowałem, aby osiągnąć ten wynik, więc nie jestem pewien, czy kodowałem elegancko. Jeśli zjawia się ekspert leśny, słucham, jakie ulepszenia można wprowadzić.

\documentclass[border=5mm]{standalone}
\usepackage{forest}
\usetikzlibrary{arrows.meta}
\useforestlibrary{linguistics}

\begin{document}
\begin{forest}
% Styling
for tree={
    align=center,
    parent anchor=south,
    child anchor=north,
    edge={thick, -{Stealth[]}},
    l sep+=10pt,
    edge path={\noexpand\path [draw, \forestoption{edge}] (!u.parent anchor) -- +(0,-10pt) -| (.child anchor)\forestoption{edge label};
},
if level=0{inner xsep=-15pt,tikz={\draw [thick] (.south east) -- (.south west);}
}{}
}
%
[Alphabet
    [a
        [b,name=b]
        [c,s sep=10,
        [f,name=f,s sep=30,
            [,phantom]
            [z,name=z,edge={white}]
        ]
        [,phantom]          
        ] 
    ]
    [b
        [d,name=d]
        [e,s sep=9
            [g,name=g]
            [,phantom]         
        ] 
    ]
]
\draw[thick,shorten >=2pt] (b.south) -- +(0,-10pt) -| (f.north);
\draw[thick,shorten >=2pt] (d.south) -- +(0,-10pt) -| (g.north);
\draw[thick,shorten >=2pt] (g.south east) -- +(0,-10pt) -| (z.north);
\draw[thick,-{Stealth[]}] (f.south west) -- +(0,-10pt) -| (z.north);
\end{forest}

\end{document}

Stara odpowiedź

Może być bardziej eleganckie rozwiązanie, ale oto moja propozycja.

\documentclass[border=5mm]{standalone}
\usepackage{forest}
\usetikzlibrary{arrows.meta}
\useforestlibrary{linguistics}
%\usepackage{fullpage}
%\usepackage[utf8]{inputenc}
%\usepackage{tikz}
%\usetikzlibrary{arrows,shapes,positioning,shadows,trees}
%\usepackage{mdframed}
%\usepackage{boxedminipage}


\begin{document}
\begin{forest}
% Styling
for tree={
    align=center,
    parent anchor=south,
    child anchor=north,
    edge={thick, -{Stealth[]}},
    l sep+=10pt,
    edge path={\noexpand\path [draw, \forestoption{edge}] (!u.parent anchor) -- +(0,-10pt) -| (.child anchor)\forestoption{edge label};
},
if level=0{inner xsep=-15pt,tikz={\draw [thick] (.south east) -- (.south west);}
}{}
}
%
[Alphabet
    [a
        [b,name=b]
        [c,name=c
            [,phantom]
            [z,name=z]
        ] 
    ]
    [b
        [d,name=d]
        [e,name=e] 
    ]
]
\draw[thick,shorten >=2pt] (b.south) -- +(0,-10pt) -| (z.north);
\draw[thick,shorten >=2pt] (d.south) -- +(0,-10pt) -| (z.north);
\draw[thick,shorten >=2pt] (e.south) -- +(0,-10pt) -| (z.north);
\end{forest}

\end{document}