ASD Ćwiczenia 8: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Amal (dyskusja | edycje)
Nie podano opisu zmian
Nie podano opisu zmian
 
(Nie pokazano 4 wersji utworzonych przez 2 użytkowników)
Linia 12: Linia 12:


Oznaczmy rozmiar drzewa <math>T_h</math> przez <math>a_h</math>. Mamy
Oznaczmy rozmiar drzewa <math>T_h</math> przez <math>a_h</math>. Mamy
<math>a_0 = 1</math>, <math>a_1 = 2</math>, <math>a_{h+1} = a_h+a_{h-1}+1</math> dla <math>h>0</math>. Porównując kilka pierwszych wyrazów tego ciągu z początkowymi wyrazami ciągu Fibonacciego <math>\langle F_h\rangle</math> zgadujemy, że <math>a_h = F{h+3}-1</math> (co łatwo sprawdzić przez indukcję) - dlatego <math>T_h</math> noszą nazwę '''drzew Fibonacciego'''. Mamy zatem <math>a_h = \Theta(\phi^h)</math>.
<math>a_0 = 1</math>, <math>a_1 = 2</math>, <math>a_{h+1} = a_h+a_{h-1}+1</math> dla <math>h>0</math>. Porównując kilka pierwszych wyrazów tego ciągu z początkowymi wyrazami ciągu Fibonacciego <math>\langle F_h\rangle</math> zgadujemy, że <math>a_h = F_{h+3}-1</math> (co łatwo sprawdzić przez indukcję) - dlatego <math>T_h</math> noszą nazwę '''drzew Fibonacciego'''. Mamy zatem <math>a_h = \Theta(\phi^h)</math>.
</div>
</div>
</div>
</div>
Linia 36: Linia 36:


Zadanie 4
Zadanie 4
Chcemy, żeby nasz słownik udostępniał dodatkową operację Select(S,k), zwracającą k-ty najmniejszy element w S. Jak zmodyfikować drzewa AVL, żeby pozwalały wykonywac operację Select w czasie logarytmicznym?
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
Rozwiązanie
<div class="mw-collapsible-content" style="display:none">
W każdym węźle przechowujemy atrybut 'rozmiar poddrzewa'. Taki atrybut można łatwo uaktualniać podczas rotacji i pozwala on na zlokalizowanie k-tego elementu przy pomocy jednego zejścia od korzenia w dół drzewa.
</div>
</div>
Zadanie 5


Udowodnij Lemat 1.
Udowodnij Lemat 1.
Linia 46: Linia 59:


(1) Węzeł <math>u</math> nie istnieje, bo <math>v</math> jest synem korzenia <math>w</math>. <br>
(1) Węzeł <math>u</math> nie istnieje, bo <math>v</math> jest synem korzenia <math>w</math>. <br>
Do wykonania mamy tylko ROT1<math>(v, w)</math>, a do zużycia <math>3(\mu'(v)-\mu(v))+1</math> jednostek kredytu. Mamy <math>\mu'(v) = \mu(w)</math> oraz <math>\mu'(w) \le \mu'(v)</math>.
Do wykonania mamy tylko ROT1<math>(v, w)</math>, a do zużycia <math>3(\mu'(v)-\mu(v))+1</math> jednostek kredytu. Mamy <math>\mu'(v) = \mu(w)</math> oraz <math>\mu'(w) \le \mu'(v)</math>.<br>
 
Na utrzymanie niezmiennika (***) potrzeba <br>
Na utrzymanie niezmiennika (***) potrzeba <br>
<math>\mu'(v)+\mu'(w)-\mu(v)-\mu(w) = \mu'(w)-\mu(v) \le \mu'(v)-\mu(v) \le 3(\mu'(v)-\mu(v)</math><br>
<math>\mu'(v)+\mu'(w)-\mu(v)-\mu(w) = \mu'(w)-\mu(v) \le \mu'(v)-\mu(v) \le 3(\mu'(v)-\mu(v)</math><br>
Linia 66: Linia 80:




Zadanie
Zadanie 6


Opisane tu operacje Insert i Delete dla B-drzew są ''dwuprzebiegowe'': najpierw schodzimy od korzenia do liścia, a następnie wracamy w górę drzewa przywracając warunki równowagi. Zaprojektuj wymagające z grubsza o połowę odwołań do dysku mniej ''jednoprzebiegowe'' algorytmy wstawiania i usuwania kluczy z B-drzewa, w których przywracanie równowagi odbywa się od razu podczas marszu w dół drzewa.
Opisane tu operacje Insert i Delete dla B-drzew są ''dwuprzebiegowe'': najpierw schodzimy od korzenia do liścia, a następnie wracamy w górę drzewa przywracając warunki równowagi. Zaprojektuj wymagające z grubsza o połowę odwołań do dysku mniej ''jednoprzebiegowe'' algorytmy wstawiania i usuwania kluczy z B-drzewa, w których przywracanie równowagi odbywa się od razu podczas marszu w dół drzewa.
Linia 75: Linia 89:
<div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible-content" style="display:none">
Podstawowy pomysł polega na zadbaniu o to, by przy wstawianiu ojciec aktualnego węzła nigdy nie był całkowicie wypełniony, a przy usuwaniu - miał przynajmniej o jeden klucz więcej niż dozwolone minimum. Szczegóły można znaleźć w książce [CLRS], podrozdz. 18.2 i 18.3.
Podstawowy pomysł polega na zadbaniu o to, by przy wstawianiu ojciec aktualnego węzła nigdy nie był całkowicie wypełniony, a przy usuwaniu - miał przynajmniej o jeden klucz więcej niż dozwolone minimum. Szczegóły można znaleźć w książce [CLRS], podrozdz. 18.2 i 18.3.
</div>
</div>
Zadanie 7
Chcemy rozszerzyć nasz zestaw operacji słownikowych o dwie dodatkowe: <br>
Join(S1,S2) łączy dwa słowniki w jeden, przy założeniu, że wszystkie klucze w S1 są mniejsze niż wszystkie klucze w S2; <br>
Split(S,x) dzieli słownik S na dwa słowniki: pierwszy złożony z elementów mniejszych bądź równych x i drugi zlożony z elementów większych od x.<br>
Jak zrealizować te operacje<br>
(a) dla B-drzew;<br>
(b) dla drzew AVL<br>
z kosztem proporcjonalnym do wysokości przetwarzanych drzew?
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
Rozwiązanie
<div class="mw-collapsible-content" style="display:none">
(a) Join w B-drzewach można zrealizować następująco:
Niech h1 i h2 oznaczają wysokości obu drzew; dla ustalenia uwagi załóżmy, że <math>h1 > h2</math>. Schodzimy w S1 do węzła o wysokości <math>h2+1</math>, dołączamy S2 jako jego skrajnie prawego syna i poprawiamy zrównoważenie jak przy wstawianiu.<br>
W celu wykonania Split schodzimy do węzła z kluczem $x$, po czym wracamy do korzenia, wykonując Join osobno dla drzew po lewej i po prawej stronie ścieżki. Koszt Join jest w zasadzie proporcjonalny do ''różnicy wysokości'' łączonych drzew, więc łączny koszt wyjdzie proporcjonalny do wysokości $S$.
(b) W przypadku AVL idea jest podobna jak poprzednio, ale pojawia się trochę problemów technicznych; szczegółowe rozwiązanie można znaleźć na przykład w książce D. Knutha "Sztuka programowania", WNT 2002, podrozdz. 6.2.3, str. 509.
</div>
</div>
</div>
</div>

Aktualna wersja na dzień 10:09, 31 sie 2023

Zadanie 1

Udowodnij, że wysokość drzewa AVL jest logarytmiczna względem jego rozmiaru.

Rozwiązanie


Zadanie 2

Oblicz, ile jest różnych drzew Fibonacciego o wysokości h.

Rozwiązanie


Zadanie 3

Napisz pseudokod operacji Insert i Delete w drzewach AVL.


Zadanie 4

Chcemy, żeby nasz słownik udostępniał dodatkową operację Select(S,k), zwracającą k-ty najmniejszy element w S. Jak zmodyfikować drzewa AVL, żeby pozwalały wykonywac operację Select w czasie logarytmicznym?

Rozwiązanie


Zadanie 5

Udowodnij Lemat 1.

Rozwiązanie


Zadanie 6

Opisane tu operacje Insert i Delete dla B-drzew są dwuprzebiegowe: najpierw schodzimy od korzenia do liścia, a następnie wracamy w górę drzewa przywracając warunki równowagi. Zaprojektuj wymagające z grubsza o połowę odwołań do dysku mniej jednoprzebiegowe algorytmy wstawiania i usuwania kluczy z B-drzewa, w których przywracanie równowagi odbywa się od razu podczas marszu w dół drzewa.

Rozwiązanie


Zadanie 7

Chcemy rozszerzyć nasz zestaw operacji słownikowych o dwie dodatkowe:
Join(S1,S2) łączy dwa słowniki w jeden, przy założeniu, że wszystkie klucze w S1 są mniejsze niż wszystkie klucze w S2;
Split(S,x) dzieli słownik S na dwa słowniki: pierwszy złożony z elementów mniejszych bądź równych x i drugi zlożony z elementów większych od x.
Jak zrealizować te operacje
(a) dla B-drzew;
(b) dla drzew AVL
z kosztem proporcjonalnym do wysokości przetwarzanych drzew?

Rozwiązanie