Informatyka dla klas III - Badanie drzew binarnych

Dla danego drzewa binarnego określić:

  1. Długość najdłuższej ścieżki od korzenia do liścia (czyli wysokość drzewa).
  2. Długość najkrótszej ścieżki od korzenia do liścia.
  3. Liczbę węzłów na każdym poziomie.
  4. Liczbę liści.
  5. Liczbę węzłów zawierających tylko jednego syna
  6. Sumę danych zawartych w węzłach.

Na pierwszy rzut oka zadanie wydaje się być skomplikowane. Jednakże rozwiążemy je za pomocą opisanego na poprzedniej lekcji przejścia DFS:preorder. Algorytm DFS gwarantuje nam odwiedzenie każdego węzła drzewa, jeśli węzłem startowym będzie jego korzeń. Do wykonania naszego zadania w strukturze węzła będziemy potrzebowali dodatkowe pole level, w którym zostanie umieszczony numer poziomu zawierającego dany węzeł.

 

struct BTNode
{
  BTNode * left;
  BTNode * right;
  int level;
  typ_danych data;
};

 

Kolejnym problemem jest sposób wprowadzania drzewa. Można go rozwiązać na kilka sposobów. Tutaj postąpimy w sposób następujący:

 

Pierwsza liczba n będzie określała ilość wszystkich węzłów w drzewie. Umówmy się, że węzły ponumerujemy kolejnymi liczbami od 0 do n-1 idąc od strony lewej do prawej na kolejnych poziomach.

Kolejne dane występują jako n trójek liczb. Każdy węzeł jest opisany jedną trójką liczb. Pierwsza trójka odnosi się do węzła nr 0, druga do węzła nr 1, itd.

Trójka liczb dla danego węzła określa kolejno: daną dla węzła, numer węzła będącego lewym synem, numer węzła będącego prawym synem. Jeśli węzeł nie posiada syna, to jego numer wynosi 0 (nie spowoduje to dwuznaczności, ponieważ numer 0 jest zarezerwowany dla korzenia, a korzeń nie jest synem żadnego węzła).

 

Przykład:

 

Na rysunku poniżej przedstawione jest drzewo binarne. Wewnątrz węzłów znajdują się przechowywane w tych węzłach liczby. Numery węzłów są podane w kolorze czerwonym pod każdym węzłem. Na przykład węzeł nr 3 przechowuje liczbę 32 i posiada dwóch synów: lewego – węzeł 7 i prawego – węzeł 8.

 

  12
5 1 2
11 3 4
7 5 6
32 7 8
-16 0 9
21 10 11
-2 0 0
3 0 0
17 0 0
-5 0 0
4 0 0
1 0 0
   Liczba węzłów
węzeł   0: synowie 1 i 2
węzeł   1: synowie 3 i 4
węzeł   2: synowie 5 i 6
węzeł   3: synowie 7 i 8
węzeł   4: prawy syn 9
węzeł   5: synowie 10 i 11
węzeł   6: brak synów
węzeł   7: brak synów
węzeł   8: brak synów
węzeł   9: brak synów
węzeł 10: brak synów
węzeł 11: brak synów


Zasada odczytu danych będzie następująca:

  1. Odczytujemy n.
  2. Tworzymy dynamicznie tablicę n wskaźników do węzłów drzewa.
  3. Dynamicznie tworzymy n węzłów i ich adresy zapamiętujemy we wskaźnikach.
  4. Odczytujemy n trójek liczb. Numer trójki określa numer węzła. Pierwszą liczbę wstawiamy w pole data, następne dwie liczby, jeśli są różne od zera, darzą numery wskaźników w tablicy, które należy przepisać odpowiednio w pole left i right węzła.
  5. Po odczycie danych zapamiętujemy w osobnej zmiennej wskazanie korzenia, czyli pierwszy wskaźnik w tablicy wskaźników.
  6. Tablicę dynamiczną wskaźników usuwamy z pamięci.

 

Długość najdłuższej ścieżki

Tworząc węzły, zerujemy w nich pola level. Przed rozpoczęciem przeglądania drzewa tworzymy zmienną maxpath, w której umieszczamy wartość 0. W trakcie przechodzenia drzewa przetwarzamy węzeł:
  1. Jeśli posiada syna, to w polu level syna umieszczamy zawartość pola level węzła powiększoną o 1. W ten sposób dzieci będą miały zawsze numer poziomu o 1 większy od swoich rodziców.
  2. Porównujemy pole level przetwarzanego węzła ze zmienną maxpath. Jeśli level ma wartość większą, to zapisujemy ją w maxpath. Po przejściu całego drzewa maxlevel będzie zawierał największą wartość poziomu, czyli wysokość drzewa.

Długość najkrótszej ścieżki do liścia

Przed rozpoczęciem przeglądania drzewa tworzymy zmienną minpath, w której umieszczamy największą wartość całkowitą (dla liczb 32 bitowych jest to 2147483647). W trakcie przechodzenia drzewa sprawdzamy, czy węzeł jest liściem (tak będzie, jeśli pola left i right zawierają wskazanie puste). Jeśli tak, to porównujemy wartość pola level ze zmienną minpath. Jeśli jest mniejsze, zapamiętujemy je w minpath. Po przejściu całego drzewa minpath będzie zawierało długość najkrótszej ścieżki.

 

Liczba węzłów na każdym poziomie

Przed rozpoczęciem przeglądania drzewa tworzymy dynamicznie tablicę levelcount liczników i zerujemy je. Kolejne liczniki będą zliczały węzły na kolejnych poziomach. Tworząc tablicę musimy określić liczbę poziomów. W najbardziej niekorzystnym przypadku będzie ich n (drzewo binarne posiadające wszystkie węzły oprócz ostatniego z jednym synem). Dlatego tworzymy tablicę n elementową. Faktyczną wysokość drzewa poznamy dopiero po wykonaniu przejścia DFS.

W trakcie wykonywania DFS zwiększamy o 1 licznik o indeksie równym zawartości pola level – zliczymy węzeł na danym poziomie. Po przejściu drzewa wyświetlamy zawartości liczników od 0 do maxpath.

 

Liczba liści

Przed rozpoczęciem przeglądania drzewa tworzymy zmienną leafcount i nadajemy jej wartość 0. W trakcie przeglądania drzewa sprawdzamy, czy bieżący węzeł jest liściem (pola left i right zawierają wskazanie puste) i jeśli tak, to zwiększamy o 1 zmienną leafcount. Po przejściu drzewa zmienna zawiera liczbę liści.

 

Liczba węzłów z jednym synem

Przed rozpoczęciem przeglądania drzewa tworzymy zmienną onechildcount i nadajemy jej wartość 0. W trakcie przeglądania drzewa sprawdzamy, czy bieżący węzeł posiada tylko jednego syna (tylko jedno z pól left i right zawiera wskazanie puste) i jeśli tak, to zwiększamy o 1 zmienną onechildcount. Po przejściu drzewa zmienna zawiera liczbę węzłów z jednym synem.

 

Suma zawartości węzłów

Przed rozpoczęciem przeglądania drzewa tworzymy zmienną nodesum i nadajemy jej wartość 0. W trakcie przeglądania do zmiennej nodesum dodajemy zawartość pola data bieżącego węzła. Po przejściu drzewa w nodesum będzie suma zawartości wszystkich węzłów drzewa.

 

Przykładowe dane wejściowe (jest to drzewo z przykładu podanego powyżej):

 

12
5 1 2
11 3 4
7 5 6
32 7 8
-16 0 9
21 10 11
-2 0 0
3 0 0
17 0 0
-5 0 0
4 0 0
1 0 0

 

Wynik
12
5 1 2
11 3 4
7 5 6
32 7 8
-16 0 9
21 10 11
-2 0 0
3 0 0
17 0 0
-5 0 0
4 0 0
1 0 0

maxpath = 3
minpath = 2

level 0 : number of nodes = 1
level 1 : number of nodes = 2
level 2 : number of nodes = 4
level 3 : number of nodes = 5

leafcount = 6
onechildcount = 1
nodesum = 78

 



List do administratora Serwisu Edukacyjnego Nauczycieli I LO

Twój email: (jeśli chcesz otrzymać odpowiedź)
Temat:
Uwaga: ← tutaj wpisz wyraz  ilo , inaczej list zostanie zignorowany

Poniżej wpisz swoje uwagi lub pytania dotyczące tego rozdziału (max. 2048 znaków).

Liczba znaków do wykorzystania: 2048

 

W związku z dużą liczbą listów do naszego serwisu edukacyjnego nie będziemy udzielać odpowiedzi na prośby rozwiązywania zadań, pisania programów zaliczeniowych, przesyłania materiałów czy też tłumaczenia zagadnień szeroko opisywanych w podręcznikach.



   I Liceum Ogólnokształcące   
im. Kazimierza Brodzińskiego
w Tarnowie

©2017 mgr Jerzy Wałaszek

Dokument ten rozpowszechniany jest zgodnie z zasadami licencji
GNU Free Documentation License.