JustPaste.it

Algorytmy sortujące - sortowanie poprzez kopcowanie

c73a4e87d3dd746911b1d37f91c86b58.gif

Dotychczas operowaliśmy na prostych strukturach danych, takich jak tablice. W tablicy elementy ułożone są zgodnie z ich numeracją, czyli indeksami. Jeśli za punkt odniesienia weźmiemy element d[i] (i = 2,3,..,n-1; n - liczba elementów w tablicy), to elementem poprzedzającym go będzie element o mniejszym o 1 indeksie, czyli d[i - 1]. Elementem następnym będzie element o indeksie o 1 większym, czyli d[i + 1]. Jest to tzw. hierarchia liniowa - elementy następują jeden za drugim. Graficznie możemy przedstawić to tak:

af8910a09488ba44a12cb93b080d7cfd.gif

Pierwszy element d[1] nie posiada poprzednika (ang. predecessor - elementu poprzedzającego w ciągu). Ostatni element d[n] nie posiada następnika (ang. successor - elementu następnego w ciągu). Wszystkie pozostałe elementy posiadają poprzedniki i następniki.

Drzewo binarne jest hierarchiczną strukturą danych, którego elementy będziemy nazywali węzłami (ang. node) lub wierzchołkami. W hierarchii liniowej każdy element może posiadać co najwyżej jeden następnik. W drzewie binarnym każdy węzeł może posiadać dwa następniki (stąd pochodzi nazwa drzewa - binarny = dwójkowy, zawierający dwa elementy), które nazwiemy potomkami. dziećmi lub węzłami potomnymi danego węzła (ang. child node).

9f2ce6d159a351b9350718696698edec.gif

Węzły są połączone krawędziami symbolizującymi następstwo kolejnych elementów w strukturze drzewa binarnego. Według rysunku po prawej stronie węzeł A posiada dwa węzły potomne: B i C. Węzeł B nosi nazwę lewego potomka (ang. left child node), a węzeł C nosi nazwę prawego potomka (ang. right child node).

Z kolei węzeł B posiada węzły potomne D i E, a węzeł C ma węzły potomne F i G. Jeśli dany węzeł nie posiada dalszych węzłów potomnych, to jest w strukturze drzewa binarnego węzłem terminalnym. Taki węzeł nosi nazwę liścia (ang. leaf node). Na naszym rysunku liściami są węzły terminalne D, E, F i G.

Rodzicem, przodkiem (ang. parent node) lub węzłem nadrzędnym będziemy nazywać węzeł leżący na wyższym poziomie hierarchii drzewa binarnego. Dla węzłów B I C węzłem nadrzędnym jest węzeł A. Podobnie dla węzłów D i E węzłem nadrzędnym będzie węzeł B, a dla F i G będzie to węzeł C.

Węzeł nie posiadający rodzica nazywamy korzeniem drzewa binarnego (ang. root node). W naszym przykładzie korzeniem jest węzeł A. Każde drzewo binarne, które zawiera węzły posiada dokładnie jeden korzeń.

14c82c30fcca73c5486c9c1aff28014d.gif

Jeśli chcemy przetwarzać za pomocą komputera struktury drzew binarnych, to musimy zastanowić się nad sposobem reprezentacji takich struktur w pamięci. Najprostszym rozwiązaniem jest zastosowanie zwykłej tablicy n elementowej. Każdy element tej tablicy będzie reprezentował jeden węzeł drzewa binarnego. Pozostaje nam jedynie określenie związku pomiędzy indeksami elementów w tablicy a położeniem tych elementów w strukturze drzewa binarnego.

Zastosujmy następujące odwzorowanie:

  • Element d[1] będzie zawsze korzeniem drzewa.
  • i-ty poziom drzewa binarnego wymaga 2i-1 węzłów. Będziemy je kolejno pobierać z tablicy.

Otrzymamy w ten sposób następujące odwzorowanie elementów tablicy w drzewo binarne:

4a1e6d2402ac2879ebae85ea1b70d994.gif

Dla węzła k-tego wyprowadzamy następujące wzory:

358b759114691a18979a6783cdb2a699.gif węzły potomne mają indeksy równe:
2k - lewy potomek
2k+1 -
prawy potomek

węzeł nadrzędny ma indeks równy [k / 2] (dzielenie całkowitoliczbowe)

 

Sprawdź, iż podane wzory są również spełnione w drzewach binarnych o większych rozmiarach niż prezentuje nasz przykład (pomocna może być kartka papieru).

a942f1239f49bacc34f0b371505a7f68.gifSkonstruować drzewo binarne z elementów zbioru {7 5 9 2 4 6 1}

 

Operacja Opis
71cab253d7c4518d41a24e0ca19477ef.gif
7 5 9 2 4 6 1
Konstrukcję drzewa binarnego rozpoczynamy od korzenia, który jest pierwszym elementem zbioru, czyli liczbą 7.
d808e4e63c66c097d2db8ae7757b3e19.gif
7 5 9 2 4 6 1
Do korzenia dołączamy dwa węzły potomne, które leżą obok w zbiorze. Są to dwa kolejne elementy, 5 i 9.
bf80f24f8ef603e013e0c5a8fe7c43c7.gif
7 5 9 2 4 6 1
Do lewego węzła potomnego (5) dołączamy jego węzły potomne. Są to kolejne liczby w zbiorze, czyli 2 i 4.
d20b794562d6ce9e5b6a56c1fe08b9a6.gif
7 5 9 2 4 6 1
Pozostaje nam dołączyć do prawego węzła ostatnie dwa elementy zbioru, czyli liczby 6 i 1. Drzewo jest kompletne.

d1b4917d3a498223fca38026cdccd69a.gif

 

Umówmy się na potrzeby tego artykułu, iż binarne drzewo jest zrównoważone i uporządkowane, jeśli na wszystkich poziomach za wyjątkiem ostatniego posiada maksymalną liczbę węzłów, a na poziomie ostatnim węzły są ułożone kolejno od lewej strony. Innymi słowy, jeśli ostatni węzeł drzewa binarnego posiada numer i-ty, to drzewo zawiera wszystkie węzły od numeru 1 do i.

Warunek ten gwarantuje nam, iż każdy element tablicy będzie reprezentował pewien węzeł w drzewie binarnym - czyli w tej strukturze nie wystąpią dziury.

4072660cf550235576a7018612917f81.gif

Drzewo po lewej stronie nie posiada węzła d[7]. Ale posiada wszystkie węzły od d[1] do d[6], jest zatem zrównoważone i uporządkowane. Można je bez problemu przedstawić za pomocą tablicy elementów od d[1] do d[6].

Drzewo po prawej stronie nie posiada węzła d[5]. Takiego drzewa nie przedstawimy poprawnie za pomocą tablicy elementów od d[1] do d[7], ponieważ nie mamy możliwości zaznaczenia (bez dodatkowych zabiegów), iż element d[5] nie należy do struktury drzewa. Zatem nie będzie to uporządkowane i zrównoważone drzewo binarne.

W uporządkowanych i zrównoważonych drzewach binarnych bardzo prosto można sprawdzić, czy k-ty węzeł jest liściem. Będzie tak, jeśli węzeł ten nie posiada węzłów potomnych. Zatem, jeśli drzewo binarne składa się z n węzłów, to wystarczy sprawdzić, czy 2k > n. Jeśli tak, węzeł jest liściem. Jeśli nie, węzeł posiada potomka o indeksie 2k, zatem nie może być liściem.

b09d8dc81f560df2daedc1b0630692cd.gif

Ścieżką nazwiemy ciąg węzłów drzewa binarnego spełniających warunek, iż każdy węzeł poprzedni jest rodzicem węzła następnego. Jeśli ścieżka składa się z k węzłów, to długością ścieżki jest liczba k - 1.

ca593349a9a89f3e75e0d070df06dd64.gif

Na powyższym rysunku zaznaczona została ścieżka biegnąca poprzez węzły {d[1], d[3], d[6], d[13]}. Ścieżka ta zawiera cztery węzły, ma zatem długość równą 3.

Wysokością drzewa binarnego nazwiemy długość najdłuższej ścieżki od korzenia do liścia. W powyższym przykładzie najdłuższa taka ścieżka ma długość 3, zatem zaprezentowane drzewo binarne ma wysokość równą 3.

Dla n węzłów zrównoważone drzewo binarne ma wysokość równą:

h = [log2n]

4f1fabca56393f193e9efc3a2b730748.gif
węzeł  (ang. node)  -  element drzewa binarnego
rodzic, węzeł nadrzędny, przodek  (ang, parent node)  - węzeł leżący o 1 poziom wyżej w hierarchii
dziecko, potomek, węzeł potomny  (ang. child node)  - węzeł leżący o 1 poziom niżej w hierarchii, dla którego bieżący węzeł jest rodzicem.
korzeń drzewa  (ang. root node)  - pierwszy węzeł na najwyższym poziomie hierarchii, który nie posiada rodzica
liść, węzeł terminalny  (ang. leaf node)  - węzeł nie posiadający węzłów potomnych
ścieżka  (ang. path)  - droga na drzewie binarnym wiodąca poprzez poszczególne wierzchołki

b7524d2edb0f34c43e5c80f5c87db35b.gif
DLA
GENIUSZA

c99f456e2fd1863d6e98d5acdd40f142.gif

  1. Zaprojektuj algorytm, który wyznacza ścieżkę od korzenia drzewa binarnego do wskazanego węzła. Na podstawie algorytmu napisz odpowiedni program w wybranym języku programowania.

  2. Wykorzystując zaprojektowany w zadaniu 1 algorytm napisz program, który dla zadanego drzewa binarnego wyznacza wszystkie ścieżki od korzenia do poszczególnych liści.

  3. Zaprojektuj algorytm, który sprawdza, czy istnieje ścieżka pomiędzy dwoma węzłami drzewa binarnego. Na podstawie tego algorytmu napisz program w wybranym języku programowania.

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

 

Źródło: mgr Jerzy Wałaszek