Grafy (3): drzewa
Wykłady z matematyki dyskretnej dla informatyków i teleinformatyków
UTP Bydgoszcz
13
Drzewo
Definicja.
Drzewo to graf acykliczny i spójny.
Wniosek. Drzewo nie ma pętli i nie ma krawędzi wielokrotnych.
Przykład.
Las
Definicja.
Las to graf acykliczny.
Wniosek.
Spójne składowe lasu to drzewa.
Przykład.
Jeszcze kilka definicji
Liść drzewa to wierzchołek o stopniu 1.
Przykład.
Liście
Fakt. Każde drzewo skończone o co najmniej jednej krawędzi ma co najmniej dwa liście.
Uzasadnienie.
Niech w1. . . wm będzie najdłuższą drogą acykliczną w drzewie. Wtedy wierzchołki w1 oraz wm są liśćmi: oczywiście w1 6= wm (droga jest acykliczna) i mają stopień 1 (gdyby nie, to istniałaby droga dłuższa od w1. . . wm).
Drzewa
Twierdzenie.
Drzewo mające n wierzchołków ma n − 1 krawędzi.
Dowód indukcyjny.
Dla n = 2 drzewo ma tylko jedną krawędź.
Drzewo mające n wierzchołków ma n − 1 krawędzi
Załóżmy, że dla n > 2 każde drzewo mające n wierzchołków ma n − 1krawędzi.
Niech T będzie drzewem o n + 1 wierzchołkach. Z poprzedniego faktu wiemy, że T ma liść. Jeśli usuniemy z T wierzchołek będący liściem i usuniemy krawędź wychodzącą z tego wierzchołka, to otrzymamy drzewo o n wierzchołkach.
Z założenia indukcyjnego ten graf ma n − 1krawędzi, więc T ma n krawędzi.
Drzewa spinające
Fakt.
Jeśli G jest grafem spójnym i jeśli D jest minimalnym podrafem w G łączącym wszystkie wierzchołki, to D jest acykliczny (czyli jest drzewem).
Uzasadnienie.
Gdyby D zawierał cykl, to usuwając jedną krawędź tego cyklu nadal dostaniemy podraf łączący wszystkie wierzchołki G , co jest sprzeczne z minimalnością G .
Definicja.
Drzewem spinającym D grafu G jest drzewo zawierające wszystkie wierzchołki tego grafu.
Drzewa spinające
Przykład.
Graf i jedno z setek drzew spinających tego grafu.
Drzewo spinające
Twierdzenie. Każdy graf spójny ma przynajmniej jedno drzewo spinające.
Dowód.
Graf G jest spójny. Niech H będzie podgrafem spójnym, który zawiera wszystkie wierzchołki G i możliwie najmniejszą liczbę krawędzi. Gdyby H zawierał cykl, to usuwając jedną krawędź tego cyklu nadal dostaniemy podraf spójny łączący wszystkie wierzchołki G , co jest sprzeczne z minimalnością H.
Algorytm DRZEWO(v )
Jeśli graf G jest spójny, to algorytm znajdzie drzewo spinające.
Jeśli G nie jest spójny, to algorytm znajdzie drzewo spinające spójnej składowej grafu G zawierającej wierzchołek v .
Na wejściu: wierzchołek v grafu G .
Na wyjściu: zbiór krawędzi E drzewa spinającego.
Zmienna pomocnicza:
ciąg V odwiedzanych wierzchołków.
Niech V := {v } oraz E := ∅.
Dopóki istnieje krawędź w G łącząca wierzchołek z V z wierzchołkiem spoza V , to wybierz taką krawędź łączącą u ∈ V z w /∈ V .
Dołącz w do V oraz krawędź {u, w } do E .
Przykład, algorytm DRZEWO(1)
1 2
3 4 5
6 7 8
1 2
3 4 5
6 7 8
V := {1}; E := ∅. Wybierz krawędź {1, 2}. V := {1, 2}; E := {{1, 2}}.
Wybierz krawędź {1, 3}. V := {1, 2, 3}; E := {{1, 2}, {1, 3}}.
Wybierz krawędź {1, 4}. V := {1, 2, 3, 4}; E := {{1, 2}, {1, 3}, {1, 4}}.
Wybierz krawędź {2, 5}. V := {1, 2, 3, 4, 5}; E := {{1, 2}, {1, 3}, {1, 4}, {2, 5}}.
Wybierz krawędź {3, 6}. V := {1, 2, 3, 4, 5, 6};
E := {{1, 2}, {1, 3}, {1, 4}, {2, 5}, {3, 6}}.
Wybierz krawędź {4, 7}. V := {1, 2, 3, 4, 5, 6, 7};
Przykład, algorytm DRZEWO(2)
2 1
5 4
3
7 8 6
9 2
1
5 4
3
7 8 6
9
V := {2}; E := ∅.
Wybierz krawędź {2, 4}. V := {2, 4}; E := {{2, 4}}.
Wybierz krawędź {4, 6}. V := {2, 4, 6}; E := {{2, 4}, {4, 6}}.
Wybierz krawędź {6, 9}. V := {2, 4, 6, 9}; E := {{2, 4}, {4, 6}, {6, 9}}.
Wybierz krawędź {9, 8}.
V := {2, 4, 6, 9, 8}; E := {{2, 4}, {4, 6}, {6, 9}, {9, 8}}.
Przykład, algorytm DRZEWO(3)
2 1
5 4
3
7 8 6
9 2
1
5 4
3
7 8 6
9
V := {3}; E := ∅.
Wybierz krawędź {3, 1}. V := {3, 1}; E := {{3, 1}}.
Wybierz krawędź {1, 5}. V := {3, 1, 5}; E := {{3, 1}, {1, 5}}.
Wybierz krawędź {3, 7}. V := {3, 1, 5, 7}; E := {{3, 1}, {1, 5}, {3, 7}}.
Algorytm LAS
Na wejściu: graf G (VG, EG) (skończony).
Na wyjściu: zbiór krawędzi EE lasu spinającego.
Niech VV := ∅ oraz EE := ∅.
Dopóki VV 6= VG wykonaj:
wybierz v ∈ VG \ VV
wykonaj DRZEWO(v ) otrzymując zbiór wierzchołków V i zbiór krawędzi E drzewa spinającego tej składowej spójnej grafu, która zawiera v
dołącz wierzchołki z V do VV oraz krawędzie z E do EE
Przykład, algorytm LAS
1 2
3 4 5
6 7 8
1 2
3 4 5
6 7 8
VV := {1}; EE := ∅.
Wybierz 1 ∈ VG \ VV . Wykonaj DRZEWO(1). V := {1, 2, 3, 4, 5, 6, 7, 8}
E := {{1, 2}, {1, 3}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {5, 8}}.
Dołącz wierzchołki z V do VV oraz krawędzie z E do EE VV := {1, 2, 3, 4, 5, 6, 7, 8}
Przykład, algorytm LAS
2 1
5 4
3
7 8 6
9 2
1
5 4
3
7 8 6
9
VV := ∅; EE := ∅.
Wybierz 2 ∈ VG \ VV . Wykonaj DRZEWO(2).
V := {2, 4, 6, 9, 8} E := {{2, 4}, {4, 6}, {6, 9}, {9, 8}}.
Dołącz wierzchołki z V do VV oraz krawędzie z E do EE VV := {2, 4, 6, 9, 8}
EE := {{2, 4}, {4, 6}, {6, 9}, {9, 8}}.
VV 6= VG; aa
aa
Przykład, algorytm LAS , ciąg dalszy
2 1
5 4
3
7 8 6
9 2
1
5 4
3
7 8 6
9
VV := {2, 4, 6, 8, 9}
EE := {{2, 4}, {4, 6}, {6, 9}, {9, 8}}.
VV 6= VG; wybierz 3 ∈ VG \ VV . Wykonaj DRZEWO(3).
V := {3, 1, 5, 7}; E := {{3, 1}, {1, 5}, {3, 7}}.
Dołącz wierzchołki z V do VV oraz krawędzie z E do EE VV := {2, 4, 6, 9, 8, 1, 3, 5, 7}
Korzeń
Definicja.
Drzewo z wyróżnionym korzeniem to drzewo,
w którym wyróżniamy jeden z wierzchołków, nazywany korzeniem.
Przykład. Częstokorzeńrysujemy na górze.
Drzewo poszukiwań binarnych
Obserwacja.
Zestaw słów, ciąg liczb, czy inny zbiór z ustalonym porządkiem można przedstawić w postaci drzewa z wyróżnionym korzeniem zwanego drzewem poszukiwań binarnych.
W takim drzewie każdy wierzchołek jest co najwyżej trzeciego stopnia.
(Precyzyjniejsza definicja pojawi się za cztery slajdy.)
Drzewo poszukiwań binarnych
Przykład.
Etykieta każdego wierzchołka jest (w porządku alfabetycznym) dalsza niż sąsiedniego wierzchołka lewego-dolnego, a bliższa niż sąsiedniego
wierzchołka dolnego-prawego. Ponadto w tym przykładzie na każdym poziomie etykieta z lewej strony jest wcześniejsza od etykiety po prawej.
ja
ga on
be gu my wy
dr ir ty
„Drzewo genealogiczne”
Niech T będzie drzewem z wyróżnionym korzeniem k. Umownie potraktujmy T jak graf skierowany (zwrot „strzałek” określa
„grawitacja”). Przyjmijmy, że jeśli para (u, v ) jest krawędzią tego drzewa, to wierzchołek u leży bliżej k niż wierzchołek v .
Definicja. Jeśli para (u, v ) jest krawędzią drzewa T , to U jest rodzicem v , natomiast v jest dzieckiem u. Ponadto, w jest potomkiem u, jeśli w 6= u oraz u jest jakimś wierzchołkiem jedynej drogi prostej z korzenia do wierczhołka w .
Definicja. Jeśli v jest wierzchołkiem, to poddrzewo Yv o korzeniu v jest drzewem składającym się z v , z wszystkich jego potomków oraz wszystkich krawędzi łączących te wierzchołki.
Fakt. Każdy wierzchołek (z wyjątkiem korzenia) ma dokładnie jednego
Poddrzewa
Przykład. Drzewo i jego niejednowierzchołkowe poddrzewa.
ja
ga on
be gu my wy
dr ir ty
ga
be gu
dr ir
on
my wy
ty
gu
dr ir
wy
ty
Drzewo binarne
Definicja. Drzewo binarne to drzewo z wyróżnionym korzeniem, w którym każdy wierzchołek (węzeł) ma co najwyżej dwoje dzieci: albo dziecko lewe, albo prawe, albo dwoje dzieci (lewe i prawe), albo nie ma dzieci.
Definicja. Drzewo o m rozgałęzieniach (m > 2) to drzewo, w którym każdy rodzic ma co najwyżej m dzieci oznaczanych różnymi liczbami ze zbioru {1, 2, . . . , m}.
Definicja. Drzewo o m rozgałęzieniach (m > 2) lub drzewo binarne (m = 2) jest drzewem regularnym gdy każdy rodzic ma dokładnie m dzieci.
Wysokość drzewa
Definicja. Numer poziomu wierzchołka v to długość jedynej drogi prostej od korzenia do v . Numer korzenia to zero.
Definicja. Wysokość drzewa z wyróżnionym korzeniem to największy numer poziomu wierzchołka (długość najdłuższej drogi prostej wychodzącej z korzenia).
Definicja. Regularne drzewo o m rozgałęzieniach (m > 2) lub regularne drzewo binarne (m = 2) jest pełnym drzewem o m rozgałęzieniach, jeśli wszystkie liście mają numer poziomu równy wysokości drzewa.
Przykład,
pełne drzewo o trzech rozgałęzieniach i wysokości dwa.
Drzewo to ma 13 wierzchołków, 13 = 32+13−1−1.
Drzewo pełne
Fakt. Pełne drzewo o m rozgałęzieniach i wysokości h ma mm−1h+1−1 wierzchołków.
Uzasadnienie.
Na poziomie pierwszym mamy m wierzchołków (korzeń ma m dzieci).
Każy z tych wierzchołków ma m dzieci, więc na poziomie drugim mamy m2 dzieci, ...
Sumując, mamy na wszystkich poziomach 1 + m + m2+ · · · + mh
wierzchołków. Stosujemy wzór na sumę h + 1 początkowych wyrazów ciągu geometrycznego:
1 + m + m2+ · · · + mh= 1 ·1 − mh+1
1 − m = mh+1− 1 m − 1 .
Drzewo pełne
Fakt. Pełne drzewo o m rozgałęzieniach i wysokości h ma mm−1h−1 rodziców oraz mh liści.
Przykład. Pełne drzewo o trzech rozgałęzieniach i wysokości dwa ma 4 rodziców i9 liści.
Drzewo uporządkowane
Definicja.
Uporządkowane drzewo z wyróżnionym korzeniem to takie drzewo, w którym uporządkujemy dzieci każdego rodzica (od strony lewej do prawej).
Przykład. Przyjmujemy O < R. Graf ten może przedstawiać wyniki powtarzanego rzutu monetą.
O R
OO OR RO RR
OOO OOR ORO ORR ROO ROR RRO RRR
Algorytm DRZEWO i LAS
Uwaga.
Aby sprawdzić, czy graf jest spójny wystarczy sprawdzić, czy algorytm DRZEWO(v ) (dla dowolnego wierzchołka v ) tworzy drzewo zawierające wszystkie wierzchołki grafu
lub,
równoważnie, czy algorytm LAS tworzy tylko jedno drzewo.
Uwaga.
Aby sprawdzić, czy graf G jest acykliczny wystarczy sprawdzić, czy utworzony las spinający jest całym grafem (czy kEE k = kEGk).
Algorytmy przeszukiwania w głąb drzewa z wyróżnionym korzeniem
Podamy trzy algorytmy rekurencyjne przeszukiwania w głąb (przeszukiwania z nawrotami).
Porządek prefiksowy (preorder): korzeń jest pierwszy, rodzice znajdują się przed dziećmi.
Porządek postfiksowy (postorder): korzeń jest ostatni, rodzice znajdują się po dzieciach.
Porządek inorder w drzewie binarnym: lewe dziecko znajduje się przed swoim rodzicem, a prawe po.
W tych trzech algorytmach sposób poruszania się jest taki sam.
Startujemy z wierzchołka (“patrzymy w dół”) stosując zasady:
„trzymaj się prawej”, „ jeśli koniec drogi to zawróć”.
Inna jest tylko kolejność wpisywania wierzchołków na listę.
Algorytm PREORDER(v )
Na wejściu: uporządkowane skończone drzewo z wyróżnionym korzeniem v . Na wyjściu: lista L(v ) wszystkich wierzchołków tego drzewa, na której każdy rodzic jest umieszczony przed swoimi dziećmi.
Zapisz v na liście L(v )
dla każdego dziecka w wierzchołka v (w porządku od lewej strony do prawej)
PREORDER(w ) (otrzymamy tu listę złożoną z w i jego potomków) dołącz L(w ) na końcu dotychczas uzyskanej listy L(v )
Obserwacja. Algorytm ten umieszcza wierzchołek na liście w momencie, gdy odwiedza go po raz pierwszy.
Algorytm PREORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
Wpisz v1 na listę. L(v1) = v1.
Weź pierwsze (lewe) dziecko v2 rodzica v1. Wpisz v2 na listę L(v2) = v2. Weź pierwsze (lewe) dziecko v4 rodzica v2. Wpisz v4 na listę L(v4) = v4. Wierzchołek v4 nie ma dzieci. L(v2) = v2v4.
Weź kolejne dziecko v5 rodzica v2. Wpisz v5 na listę L(v5) = v5.
Weź pierwsze (lewe) dziecko v9 rodzica v5. Wpisz v9 na listę L(v9) = v9. Wierzchołek v9 nie ma dzieci. L(v5) = v5v9.
Weź kolejne dziecko v10 rodzica v5. Wpisz v10 na listę L(v10) = v10. Wierzchołek v10 nie ma dzieci. L(v5) = v5v9v10.
Algorytm PREORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
Wpisz v1 na listę. L(v1) = v1.
Weź pierwsze (lewe) dziecko v2 rodzica v1. Wpisz v2 na listę L(v2) = v2. Weź pierwsze (lewe) dziecko v4 rodzica v2. Wpisz v4 na listę L(v4) = v4. Wierzchołek v4 nie ma dzieci. L(v2) = v2v4.
Weź kolejne dziecko v5 rodzica v2. Wpisz v5 na listę L(v5) = v5.
Weź pierwsze (lewe) dziecko v9 rodzica v5. Wpisz v9 na listę L(v9) = v9. Wierzchołek v9 nie ma dzieci. L(v5) = v5v9.
Algorytm PREORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
Wpisz v1 na listę. L(v1) = v1.
Weź pierwsze (lewe) dziecko v2 rodzica v1. Wpisz v2 na listę L(v2) = v2. Weź pierwsze (lewe) dziecko v4 rodzica v2. Wpisz v4 na listę L(v4) = v4. Wierzchołek v4 nie ma dzieci. L(v2) = v2v4.
Weź kolejne dziecko v5 rodzica v2. Wpisz v5 na listę L(v5) = v5.
Weź pierwsze (lewe) dziecko v9 rodzica v5. Wpisz v9 na listę L(v9) = v9. Wierzchołek v9 nie ma dzieci. L(v5) = v5v9.
Weź kolejne dziecko v10 rodzica v5. Wpisz v10 na listę L(v10) = v10. Wierzchołek v10 nie ma dzieci. L(v5) = v5v9v10.
Algorytm PREORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
Wpisz v1 na listę. L(v1) = v1.
Weź pierwsze (lewe) dziecko v2 rodzica v1. Wpisz v2 na listę L(v2) = v2. Weź pierwsze (lewe) dziecko v4 rodzica v2. Wpisz v4 na listę L(v4) = v4. Wierzchołek v4 nie ma dzieci. L(v2) = v2v4.
Weź kolejne dziecko v5 rodzica v2. Wpisz v5 na listę L(v5) = v5.
Weź pierwsze (lewe) dziecko v9 rodzica v5. Wpisz v9 na listę L(v9) = v9. Wierzchołek v9 nie ma dzieci. L(v5) = v5v9.
Algorytm PREORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
Wpisz v1 na listę. L(v1) = v1.
Weź pierwsze (lewe) dziecko v2 rodzica v1. Wpisz v2 na listę L(v2) = v2. Weź pierwsze (lewe) dziecko v4 rodzica v2. Wpisz v4 na listę L(v4) = v4. Wierzchołek v4 nie ma dzieci. L(v2) = v2v4.
Weź kolejne dziecko v5 rodzica v2. Wpisz v5 na listę L(v5) = v5.
Weź pierwsze (lewe) dziecko v9 rodzica v5. Wpisz v9 na listę L(v9) = v9. Wierzchołek v9 nie ma dzieci. L(v5) = v5v9.
Weź kolejne dziecko v10 rodzica v5. Wpisz v10 na listę L(v10) = v10. Wierzchołek v10 nie ma dzieci. L(v5) = v5v9v10.
Algorytm PREORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
Wpisz v1 na listę. L(v1) = v1.
Weź pierwsze (lewe) dziecko v2 rodzica v1. Wpisz v2 na listę L(v2) = v2. Weź pierwsze (lewe) dziecko v4 rodzica v2. Wpisz v4 na listę L(v4) = v4. Wierzchołek v4 nie ma dzieci. L(v2) = v2v4.
Weź kolejne dziecko v5 rodzica v2. Wpisz v5 na listę L(v5) = v5.
Weź pierwsze (lewe) dziecko v9 rodzica v5. Wpisz v9 na listę L(v9) = v9. Wierzchołek v9 nie ma dzieci. L(v5) = v5v9.
Algorytm PREORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
L(v2) = v2v4, L(v5) = v5v9v10.
Wszyscy potomkowie v2 zostali uwzględnieni.
L(v2) = v2v4v5v9v10. L(v1) = v1v2v4v5v9v10. aaa
aa aa aa
Algorytm PREORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
L(v1) = v1v2v4v5v9v10.
Weź kolejne dziecko v3 rodzica v1. Wpisz v3 na listę L(v3) = v3.
Weź pierwsze (lewe) dziecko v6 rodzica v3. Wpisz v6 na listę L(v6) = v6. Wierzchołek v6 nie ma dzieci. L(v3) = v3v6.
Weź kolejne dziecko v7 rodzica v7. Wpisz v7 na listę L(v7) = v7. Wierzchołek v7 nie ma dzieci. L(v3) = v3v6v7.
Weź kolejne dziecko v8 rodzica v8. Wpisz v8 na listę L(v8) = v8. Wierzchołek v nie ma dzieci. L(v ) = v v v v .
Algorytm PREORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
L(v1) = v1v2v4v5v9v10.
Weź kolejne dziecko v3 rodzica v1. Wpisz v3 na listę L(v3) = v3.
Weź pierwsze (lewe) dziecko v6 rodzica v3. Wpisz v6 na listę L(v6) = v6. Wierzchołek v6 nie ma dzieci. L(v3) = v3v6.
Weź kolejne dziecko v7 rodzica v7. Wpisz v7 na listę L(v7) = v7. Wierzchołek v7 nie ma dzieci. L(v3) = v3v6v7.
Weź kolejne dziecko v8 rodzica v8. Wpisz v8 na listę L(v8) = v8. Wierzchołek v8 nie ma dzieci. L(v3) = v3v6v7v8.
Wszystkie dzieci wierzchołka v3 zostały uwzględnione.
L(v1) = v1v2v4v5v9v10v3v6v7v8. Wszystkie dzieci wierzchołka v1 zostały
Algorytm PREORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
L(v1) = v1v2v4v5v9v10.
Weź kolejne dziecko v3 rodzica v1. Wpisz v3 na listę L(v3) = v3.
Weź pierwsze (lewe) dziecko v6 rodzica v3. Wpisz v6 na listę L(v6) = v6. Wierzchołek v6 nie ma dzieci. L(v3) = v3v6.
Weź kolejne dziecko v7 rodzica v3. Wpisz v7 na listę L(v7) = v7. Wierzchołek v7 nie ma dzieci. L(v3) = v3v6v7.
Weź kolejne dziecko v8 rodzica v3. Wpisz v8 na listę L(v8) = v8. Wierzchołek v nie ma dzieci. L(v ) = v v v v .
Algorytm PREORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
L(v1) = v1v2v4v5v9v10.
Weź kolejne dziecko v3 rodzica v1. Wpisz v3 na listę L(v3) = v3.
Weź pierwsze (lewe) dziecko v6 rodzica v3. Wpisz v6 na listę L(v6) = v6. Wierzchołek v6 nie ma dzieci. L(v3) = v3v6.
Weź kolejne dziecko v7 rodzica v3. Wpisz v7 na listę L(v7) = v7. Wierzchołek v7 nie ma dzieci. L(v3) = v3v6v7.
Weź kolejne dziecko v8 rodzica v3. Wpisz v8 na listę L(v8) = v8. Wierzchołek v8 nie ma dzieci. L(v3) = v3v6v7v8.
Wszystkie dzieci wierzchołka v3 zostały uwzględnione.
L(v1) = v1v2v4v5v9v10v3v6v7v8. Wszystkie dzieci wierzchołka v1 zostały
Algorytm PREORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
L(v1) = v1v2v4v5v9v10. L(v3) = v3.
Wierzchołek v8 nie ma dzieci. L(v3) = v3v6v7v8. Wszystkie dzieci wierzchołka v3 zostały uwzględnione.
Dopisz L(v3) na końcu listy L(v1)
L(v1) = v1v2v4v5v9v10v3v6v7v8.Wszystkie dzieci wierzchołka v1 zostały uwzględnione. Koniec.
Algorytm POSTORDER(v )
Na wejściu: uporządkowane skończone drzewo z wyróżnionym korzeniem v . Na wyjściu: lista L(v ) wszystkich wierzchołków tego drzewa, na której każdy rodzic jest umieszczony po swoich dzieciach.
Na początku lista L(v ) jest pusta, będziemy to zapisywać L(v ) = λ dla każdego dziecka w wierzchołka v (w porządku od lewej strony do prawej)
POSTORDER(w ) (otrzymamy tu listę złożoną z w i jego potomków) dołącz L(w ) na końcu dotychczas uzyskanej listy L(v )
Dołącz v na końcu listy L(v ).
Obserwacja. Algorytm ten umieszcza wierzchołek na liście w momencie, gdy odwiedza go po raz ostatni.
Algorytm POSTORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
Weź v1. L(v1) = λ.
Weź pierwsze (lewe) dziecko v2 rodzica v1. L(v2) = λ.
Weź pierwsze (lewe) dziecko v4 rodzica v2. L(v4) = λ.
Wierzchołek v4 nie ma dzieci. Wpisz v4 na listę. L(v4) = v4. L(v2) = v4. Weź kolejne dziecko v5 rodzica v2. L(v5) = λ.
Weź pierwsze (lewe) dziecko v9 rodzica v5. L(v9) = λ.
Wierzchołek v9 nie ma dzieci. Wpisz v9 na listę. L(v9) = v9. L(v5) = v9.
Algorytm POSTORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
Weź v1. L(v1) = λ.
Weź pierwsze (lewe) dziecko v2 rodzica v1. L(v2) = λ.
Weź pierwsze (lewe) dziecko v4 rodzica v2. L(v4) = λ.
Wierzchołek v4 nie ma dzieci. Wpisz v4 na listę. L(v4) = v4. L(v2) = v4. Weź kolejne dziecko v5 rodzica v2. L(v5) = λ.
Weź pierwsze (lewe) dziecko v9 rodzica v5. L(v9) = λ.
Wierzchołek v9 nie ma dzieci. Wpisz v9 na listę. L(v9) = v9. L(v5) = v9. Weź kolejne dziecko v10 rodzica v5. L(v10) = λ.
Algorytm POSTORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
Weź v1. L(v1) = λ.
Weź pierwsze (lewe) dziecko v2 rodzica v1. L(v2) = λ.
Weź pierwsze (lewe) dziecko v4 rodzica v2. L(v4) = λ.
Wierzchołek v4 nie ma dzieci. Wpiszv4 na listę. L(v4) = v4. L(v2) = v4. Weź kolejne dziecko v5 rodzica v2. L(v5) = λ.
Weź pierwsze (lewe) dziecko v9 rodzica v5. L(v9) = λ.
Wierzchołek v9 nie ma dzieci. Wpisz v9 na listę. L(v9) = v9. L(v5) = v9.
Algorytm POSTORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
Weź v1. L(v1) = λ.
Weź pierwsze (lewe) dziecko v2 rodzica v1. L(v2) = λ.
Weź pierwsze (lewe) dziecko v4 rodzica v2. L(v4) = λ.
Wierzchołek v4 nie ma dzieci. Wpiszv4 na listę. L(v4) = v4. L(v2) = v4. Weź kolejne dziecko v5 rodzica v2. L(v5) = λ.
Weź pierwsze (lewe) dziecko v9 rodzica v5. L(v9) = λ.
Wierzchołek v9 nie ma dzieci. Wpisz v9 na listę. L(v9) = v9. L(v5) = v9. Weź kolejne dziecko v10 rodzica v5. L(v10) = λ.
Algorytm POSTORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
Weź v1. L(v1) = λ.
Weź pierwsze (lewe) dziecko v2 rodzica v1. L(v2) = λ.
Weź pierwsze (lewe) dziecko v4 rodzica v2. L(v4) = λ.
Wierzchołek v4 nie ma dzieci. Wpiszv4 na listę. L(v4) = v4. L(v2) = v4. Weź kolejne dziecko v5 rodzica v2. L(v5) = λ.
Weź pierwsze (lewe) dziecko v9 rodzica v5. L(v9) = λ.
Wierzchołek v9 nie ma dzieci. Wpiszv9 na listę. L(v9) = v9. L(v5) = v9.
Algorytm POSTORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
Weź v1. L(v1) = λ.
Weź pierwsze (lewe) dziecko v2 rodzica v1. L(v2) = λ.
Weź pierwsze (lewe) dziecko v4 rodzica v2. L(v4) = λ.
Wierzchołek v4 nie ma dzieci. Wpisz v4 na listę. L(v4) = v4. L(v2) = v4. Weź kolejne dziecko v5 rodzica v2. L(v5) = λ.
Weź pierwsze (lewe) dziecko v9 rodzica v5. L(v9) = λ.
Wierzchołek v9 nie ma dzieci. Wpiszv9 na listę. L(v9) = v9. L(v5) = v9. Weź kolejne dziecko v10 rodzica v5. L(v10) = λ.
Algorytm POSTORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
L(v2) = v4. L(v5) = v9. L(v10) = λ.
Wierzchołek v10 nie ma dzieci. Wpiszv10 na listę. L(v10) = v10. L(v5) = v9v10.
Wszystkie dzieci v5 zostały odwiedzone. Wpisz v5 na listę.
L(v5) = v9v10v5. L(v2) = v4v9v10v5.
Wszystkie dzieci v2 zostały odwiedzone. Wpisz v2 na listę.
Algorytm POSTORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
L(v2) = v4. L(v5) = v9. L(v10) = λ.
Wierzchołek v10 nie ma dzieci. Wpiszv10 na listę. L(v10) = v10. L(v5) = v9v10.
Wszystkie dzieci v5 zostały odwiedzone. Wpiszv5 na listę.
L(v5) = v9v10v5. L(v2) = v4v9v10v5.
Wszystkie dzieci v2 zostały odwiedzone. Wpisz v2 na listę.
L(v5) = v4v9v10v5v2. L(v1) = v4v9v10v5v2.
Algorytm POSTORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
L(v2) = v4. L(v5) = v9. L(v10) = λ.
Wierzchołek v10 nie ma dzieci. Wpiszv10 na listę. L(v10) = v10. L(v5) = v9v10.
Wszystkie dzieci v5 zostały odwiedzone. Wpiszv5 na listę.
L(v5) = v9v10v5. L(v2) = v4v9v10v5.
Wszystkie dzieci v2 zostały odwiedzone. Wpisz v2 na listę.
Algorytm POSTORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
L(v2) = v4. L(v5) = v9. L(v10) = λ.
Wierzchołek v10 nie ma dzieci. Wpiszv10 na listę. L(v10) = v10. L(v5) = v9v10.
Wszystkie dzieci v5 zostały odwiedzone. Wpiszv5 na listę.
L(v5) = v9v10v5. L(v2) = v4v9v10v5.
Wszystkie dzieci v2 zostały odwiedzone. Wpiszv2 na listę.
L(v1) = v4v9v10v5v2.
Algorytm POSTORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
L(v1) = v4v9v10v5v2. Weź kolejne dziecko v3 rodzica v1. L(v3) = λ.
Weź pierwsze (lewe) dziecko v6 rodzica v3. L(v6) = λ.
Wierzchołek v6 nie ma dzieci. Wpisz v6 na listę. L(v6) = v6. L(v3) = v6. Weź kolejne dziecko v7 rodzica v3. L(v7) = λ.
Wierzchołek v7 nie ma dzieci. Wpisz v7 na listę. L(v7) = v7. L(v3) = v6v7. Weź kolejne dziecko v8 rodzica v3. L(v8) = λ.
Wierzchołek v8 nie ma dzieci. Wpisz v8 na listę. L(v8) = v8. L(v3) = v6v7v8.
Wszystkie dzieci v3 zostały odwiedzone. Wpisz v3 na listę.
L(v(Wykłady z matematyki dyskretnej)) = v v v v . Grafy (3): drzewa 13 56 / 1
Algorytm POSTORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
L(v1) = v4v9v10v5v2. Weź kolejne dziecko v3 rodzica v1. L(v3) = λ.
Weź pierwsze (lewe) dziecko v6 rodzica v3. L(v6) = λ.
Wierzchołek v6 nie ma dzieci. Wpisz v6 na listę. L(v6) = v6. L(v3) = v6. Weź kolejne dziecko v7 rodzica v3. L(v7) = λ.
Wierzchołek v7 nie ma dzieci. Wpisz v7 na listę. L(v7) = v7. L(v3) = v6v7. Weź kolejne dziecko v8 rodzica v3. L(v8) = λ.
Wierzchołek v8 nie ma dzieci. Wpisz v8 na listę. L(v8) = v8. L(v3) = v6v7v8.
Wszystkie dzieci v3 zostały odwiedzone. Wpisz v3 na listę.
L(v3) = v6v7v8v3.
L(v1) = v4v9v10v5v2v6v7v8v3.
Wszystkie dzieci wierzchołka v1 zostały odwiedzone. Wpisz v1 na listę.
(Wykłady z matematyki dyskretnej) Grafy (3): drzewa 13 57 / 1
Algorytm POSTORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
L(v1) = v4v9v10v5v2. Weź kolejne dziecko v3 rodzica v1. L(v3) = λ.
Weź pierwsze (lewe) dziecko v6 rodzica v3. L(v6) = λ.
Wierzchołek v6 nie ma dzieci. Wpiszv6 na listę. L(v6) = v6. L(v3) = v6. Weź kolejne dziecko v7 rodzica v3. L(v7) = λ.
Wierzchołek v7 nie ma dzieci. Wpisz v7 na listę. L(v7) = v7. L(v3) = v6v7. Weź kolejne dziecko v8 rodzica v3. L(v8) = λ.
Wierzchołek v8 nie ma dzieci. Wpisz v8 na listę. L(v8) = v8. L(v3) = v6v7v8.
Wszystkie dzieci v3 zostały odwiedzone. Wpisz v3 na listę.
L(v(Wykłady z matematyki dyskretnej)) = v v v v . Grafy (3): drzewa 13 58 / 1
Algorytm POSTORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
L(v1) = v4v9v10v5v2. Weź kolejne dziecko v3 rodzica v1. L(v3) = λ.
Weź pierwsze (lewe) dziecko v6 rodzica v3. L(v6) = λ.
Wierzchołek v6 nie ma dzieci. Wpisz v6 na listę. L(v6) = v6. L(v3) = v6. Weź kolejne dziecko v7 rodzica v3. L(v7) = λ.
Wierzchołek v7 nie ma dzieci. Wpiszv7 na listę. L(v7) = v7. L(v3) = v6v7. Weź kolejne dziecko v8 rodzica v3. L(v8) = λ.
Wierzchołek v8 nie ma dzieci. Wpisz v8 na listę. L(v8) = v8. L(v3) = v6v7v8.
Wszystkie dzieci v3 zostały odwiedzone. Wpisz v3 na listę.
L(v3) = v6v7v8v3.
L(v1) = v4v9v10v5v2v6v7v8v3.
Wszystkie dzieci wierzchołka v1 zostały odwiedzone. Wpisz v1 na listę.
(Wykłady z matematyki dyskretnej) Grafy (3): drzewa 13 59 / 1
Algorytm POSTORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
L(v1) = v4v9v10v5v2. Weź kolejne dziecko v3 rodzica v1. L(v3) = λ.
Weź pierwsze (lewe) dziecko v6 rodzica v3. L(v6) = λ.
Wierzchołek v6 nie ma dzieci. Wpisz v6 na listę. L(v6) = v6. L(v3) = v6. Weź kolejne dziecko v7 rodzica v3. L(v7) = λ.
Wierzchołek v7 nie ma dzieci. Wpisz v7 na listę. L(v7) = v7. L(v3) = v6v7. Weź kolejne dziecko v8 rodzica v3. L(v8) = λ.
Wierzchołek v8 nie ma dzieci. Wpiszv8 na listę. L(v8) = v6v7v8. L(v3) = v6v7v8.
Wszystkie dzieci v3 zostały odwiedzone. Wpisz v3 na listę.
L(v(Wykłady z matematyki dyskretnej)3) = v6v7v8v3. Grafy (3): drzewa 13 60 / 1
Algorytm POSTORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
L(v1) = v4v9v10v5v2. L(v3) = v6v7v8.
Wszystkie dzieci v3 zostały odwiedzone. Wpisz v3 na listę.
L(v3) = v6v7v8v3.
L(v1) = v4v9v10v5v2v6v7v8v3.
Wszystkie dzieci wierzchołka v1 zostały odwiedzone. Wpisz v1 na listę.
L(v1) = v4v9v10v5v2v6v7v8v3v1
Algorytm POSTORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7 v8
v9 v10
L(v1) = v4v9v10v5v2. L(v3) = v6v7v8.
Wszystkie dzieci v3 zostały odwiedzone. Wpisz v3 na listę.
L(v3) = v6v7v8v3.
L(v1) = v4v9v10v5v2v6v7v8v3.
Wszystkie dzieci wierzchołka v1 zostały odwiedzone. Wpisz v1 na listę.
Algorytm INORDER(v )
Na wejściu: uporządkowane skończone drzewo binarne z wyróżnionym korzeniem v .
Na wyjściu: lista L(v ) wszystkich wierzchołków tego drzewa, na której każdy rodzic jest umieszczony między swoim lewym i prawym dzieckiem (o ile je ma).
Na początku lista L(v ) jest pusta, będziemy to zapisywać L(v ) = λ.
Jeżeli v ma lewe dziecko w , to
INORDER(w ) (otrzymamy tu listę złożoną z w i jego potomków) dołącz L(w ) na końcu dotychczas uzyskanej listy L(v );
dołącz v na końcu listy.
Jeżeli v ma prawe dziecko u, to
INORDER(u) (otrzymamy tu listę złożoną z u i jego potomków) dołącz L(u) na końcu dotychczas uzyskanej listy L(v ).
Obserwacja. Jeżeli wierzchołek nie ma dzieci, to algorytm na wyjściu podaje tylko ten wierzchołek.
Algorytm INORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7
v8 v9
Weź v1. L(v1) = λ.
Weź pierwsze (lewe) dziecko v2 rodzica v1. L(v2) = λ.
Weź pierwsze (lewe) dziecko v4 rodzica v2. L(v4) = λ.
Wierzchołek v4 nie ma dzieci. Wpisz v4 na listę. L(v4) = v4. Powróć do v2, wpisz v2 na listę L(v2) = v4v2.
Weź kolejne dziecko v5 rodzica v2. L(v5) = λ.
Weź pierwsze (lewe) dziecko v8 rodzica v5. L(v9) = λ.
Algorytm INORDER(v ), przykład
v1
v2 v3
v4 v5 v6 v7
v8 v9
Weź v1. L(v1) = λ.
Weź pierwsze (lewe) dziecko v2 rodzica v1. L(v2) = λ.
Weź pierwsze (lewe) dziecko v4 rodzica v2. L(v4) = λ.
Wierzchołek v4 nie ma dzieci. Wpisz v4 na listę. L(v4) = v4. Powróć do v2, wpisz v2 na listę L(v2) = v4v2.
Weź kolejne dziecko v5 rodzica v2. L(v5) = λ.
Weź pierwsze (lewe) dziecko v8 rodzica v5. L(v9) = λ.
Wierzchołek v8 nie ma dzieci. Wpisz v8 na listę. L(v8) = v8. Powróć do v5, wpisz v5 na listę L(v5) = v8v5.