120 likes | 339 Views
DRZEWA. pseudokody algorytmów. Rekurencyjne przechodzenie przez drzewo – Funkcje rekurencyjne pobierają jako argument łącze do drzewa i wywołują funkcję visit, której argumentem jest węzeł drzewa. PREORDER void traverse(link h, void visit(link)) { if (h == 0) return; visit(h);
E N D
DRZEWA pseudokody algorytmów
Rekurencyjne przechodzenie przez drzewo – Funkcje rekurencyjne pobierają jako argument łącze do drzewa i wywołują funkcję visit, której argumentem jest węzeł drzewa. PREORDER void traverse(link h, void visit(link)) { if (h == 0) return; visit(h); traverse(h->l, visit); traverse(h->r, visit); }
INORDER void traverse(link h, void visit(link)) { if (h == 0) return; traverse(h->l, visit); visit(h); traverse(h->r, visit); }
POSTORDER void traverse(link h, void visit(link)) { if (h == 0) return; traverse(h->l, visit); traverse(h->r, visit); visit(h); }
Nierekurencyjne przechodzenie przez drzewo (postorder) void traverse(link h, void visit(link)) { STACK<link> s(max); s.push(h); while (!s.empty()) { visit(h = s.pop()); if (h->r != 0) s.push(h->r); if (h->l != 0) s.push(h->l); } }
Przechodzenie za pomocą przekształcania drzewa - algorytm Josepha M.Morrisa (inorder) while nie koniec if węzeł nie ma lewego syna { odwiedź go; idź w prawo; } else { uczyń go prawym synem jego poprzednika; idź do korzenia tego poddrzewa; }
void balance ( dane [ ], int pocz, int kon) { if (pocz <= kon) { int m=(pocz+kon)/2; wstaw (dane[m]); balance (dane,pocz,m-1); balance (dane, m+1,kon); } }
rotacjaprawa (S,O) // można wykonać na węźle dla // którego istnieje lewy syn { if O nie jest korzeniem zastępujemy O przez S; prawe poddrzewo S staje się lewym poddrzewem O; węzeł O staje się prawym synem węzła S; } D D OS S A B O B C C A
Pierwszy etap algorytmu DSW – prostowanie drzewa. Utwórz_winorośl (korzeń, n) //prawerotacje na węzłach // mających lewych synów { tmp = korzeń; while (tmp != NULL) if tmp ma lewego syna { wykonaj rotację tego syna względem tmp; tmp = węzeł, który został ojcem; } else tmp = węzeł, który jest prawym synem tmp; }
Drugi etap - tworzenie drzewa doskonale zrównoważonego W każdym przejściu w dół winorośli co drugi węzeł aż do pewnego miejsca jest rotowany w lewo wokół swego rodzica. Pierwsze przejście jest potrzebne, aby uzyskać różnicę liczby węzłów w winorośli i liczby węzłów w najbliższym pełnym drzewie binarnym. Utwórz_drzewo_doskonałe (n) { m = ; wykonaj n-m rotacji od korzenia; while (m>1) m=m/2; wykonaj m rotacji od korzenia; }
Algorytm wstawiania elementu do kolejki Wstawianie elementu do kolejki realizowane jest jako dodanie do kopca ostatniego liścia; potem następuje odtworzenie własności kopca (poprzez przesuwanie ostatniego liścia ku korzeniowi dopóki nie dojdzie do korzenia lub nie trafi na ojca o mniejszej wartości). WstawDoKolejki (el) { wstaw el na koniec kopca (jako ostatni liść); while ( el nie jest korzeniem i el > rodzic(el) ) zamień miejscami el i rodzic(el); }
Algorytm pobierania elementu z kolejki Pobieranie elementu z kolejki polega na pobraniu elementu z korzenia, zastąpieniu go ostatnim liściem i odtworzeniu własności kopca idąc od korzenia w dół. PobierzZKolejki ( ) { pobierz element z korzenia; wstaw do korzenia element z ostatniego liścia; usuń ostatni liść; //obydwa poddrzewa korzenia są kopcami p=korzeń; while ( p nie jest liściem i p < któregokolwiek swojego dziecka) zamień miejscami p i jego większe dziecko; }