Drzewa zbalansowane AVL i 2-3-4

Transkrypt

Drzewa zbalansowane AVL i 2-3-4
Wykład 2
Drzewa zbalansowane
AVL i 2-3-4
1
Drzewa AVL
Wprowadzenie
Drzewa AVL
– Definicja drzewa AVL
– Operacje wstawiania i usuwania
– Złożoność obliczeniowa
Drzewa 2-3-4
– Definicja drzewa 2-3-4
– Operacje wstawiania i usuwania
– Złożoność obliczeniowa
Literatura
– R. Sedgewick, “Algorytmy w C++”, rozdz. 13
2
Wprowadzenie
Drzewa BST są wygodne do efektywnego implementowania operacji:
Search, Successor, Predecessor, Minimum, Maximum, Insert, Delete
w czasie O(h), (gdzie h jest wysokością drzewa)
Jeśli drzewo jest zbalansowane (ma wtedy wysokość h = O(lg n)),
operacje te są najbardziej efektywne.
Operacje wstawiania i usuwania elementów mogą powodować, że
drzewo przestaje być zbalansowane. W najgorszym przypadku
drzewo staje się listą liniową (h = O(n))!
3
Drzewa zbalansowane
Staramy się znaleźć takie metody operowania na drzewie, żeby
pozostawało ono zbalansowane.
Jeżeli operacja Insert lub Delete spowoduje utratę zbalansowania
drzewa, będziemy przywracać tę własność w czasie co najwyżej O(lgn)
tak aby nie zwiększać złożoności.
Potrzebujemy zapamiętywać dodatkowe informacje, aby to osiągnąć.
Najbardziej popularne struktury danych dla drzew zbalansowanych to:
– Drzewa AVL: różnica wysokości dla poddrzew wynosi co najwyżej 1
– Drzewa 2-3-4 drzewa zbalansowane, ale nie binarne
– Drzewa czerwono-czarne: o wysokości co najwyżej 2(lg n + 1)
4
Drzewa AVL
Definicja: drzewem AVL nazywamy drzewo BST, takie że dla każdego z
węzłów różnica wysokości jego lewego i prawego poddrzewa wynosi co
najwyżej 1.
Skrót AVL pochodzi od nazwisk twórców: Adelson-Velskii oraz Landis
x
h
h-1 S
h-1
Sh-2
h-2
Sh
Sh = Sh–1 + Sh–2
5
Przykład drzewa AVL
4
44
2
3
17
78
1
2
32
1
88
50
1
48
62
1
6
Wysokość drzewa AVL
Twierdzenie:wysokość drzewa AVL
przechowującego n węzłów wynosi O(log n).
n(2)
3
4
n(1)
Dowód: ograniczymy najpierw n(h): minimalną ilość wewnętrznych węzłów w
drzewie AVL o wysokości h.
– widać, że n(1) = 1 i n(2) = 2
– dla n > 2, drzewo o wysokości h zawiera korzeń oraz dwa poddrzewa o
wysokościach h-1 i h-2.
stąd: n(h) = 1 + n(h-1) + n(h-2)
– wiemy, że n(h-1) > n(h-2), więc n(h) > 2n(h-2). Dalej n(h) > 2n(h-2), n(h) >
4n(h-4), n(h) > 8n(n-6), …,n(h) > 2in(h-2i)
– rozwiązując powyższe dostaniemy n(h) > 2 h/2-1 , czyli h < 2log n(h) +2
Stąd wysokość drzewa AVL wynosi O(log n)
7
Wstawianie
Wstawiamy tak jak do drzewa BST
Zawsze dodajemy nowy liść.
Przykład :
44
44
17
78
17
78
c=z
a=y
32
50
48
88
62
32
50
88
48
62
b=x
54
w
przed
po wstawieniu 54
8
Przebudowa drzewa
niech (a,b,c) będzie pożądaną listą wierzchołków w porządku inorder
Przeprowadzamy rotacje, niezbędne do przemieszczenia b na górę
poddrzewa
(pozostałe dwa
przypadki są
symetryczne)
a=z
a=z
przypadek 2: podwójna
rotacja
(prawa c, a potem lewa a)
c=y
b=y
T0
T0
b=x
c=x
T3
T1
b=y
T2
b=x
T1
T3
a=z
przypadek 1: pojedyncza
Rotacja (lewa rotacja a)
T0
T2
c=x
T1
T2
a=z
T3
T0
c=y
T1
T2
T3
9
Rotacje (przypomnienie)
Rotacja w prawo
y
x
Rotacja w lewo
x
α
δ
β
α≤x≤β i x≤y≤δ
y
α
β
δ
α≤x≤y i β≤y≤δ
10
Przykład: Left-Rotate (1)
7
4
3
x
11
6
9
19
14
2
12
y
18
22
17
20
11
Przykład: Left-Rotate (2)
7
4
3
x
11
6
9
α
2
y
18
19
14
12
22
17
β
20
δ
12
Przykład: Left-Rotate (3)
7
4
3
2
y
18
x
11
6
19
14
9
22
α
12
17
β
20
δ
13
Przykład (wstawiamy element 54)
4
44
2
3
17
78
1
2
32
1
88
50
1
48
62
1
5
44
z
2
17
3
1
1
32
78
2y
2
1
1
7
1
50
48
64
3
4
62
x
88
5
T3
54
T2
T0
T1
14
Przykład (po wstawieniu 54)
5
44
z
2
17
3
1
32
1
1
50
2
1
1
7
78
2 y
48
64
3
4
62
88
x
5
T3
54
niezbalansowane...
T2
T0
T1
44
4
3
2
17
32
1
1
48
50
x
z6
62
2 y
2
1
4
3
1
5
78
54
...zbalansowane
2
7
1
88
T2
T0
T1
T3
15
Przebudowa drzewa (pojedyncza rotacja – przyp. 1)
1 rotacja
a=z
b=y
b=y
a=z
c=x
c=x
T0
T3
T1
T3
T0
T1
T2
T2
1 rotacja
c=z
b=y
b=y
a=x
c=z
a=x
T3
T0
T2
T3
T2
T1
T0
T1
16
Przebudowa drzewa (podwójna rotacja – przyp. 2)
2 rotacje
a=z
b=x
c=y
a=z
c=y
b=x
T0
T3
T2
T0
T2
T1
T3
T1
2 rotacje
c=z
b=x
a=y
a=y
c=z
b=x
T3
T0
T2
T3
T2
T1
T0
T1
17
Usuwanie z drzewa AVL
Usuwamy, jak z drzewa BST – może spowodować to zaburzenie
zbalansowania drzewa.
Przykład:
44
44
17
62
32
50
48
17
62
78
54
Przed usunięciem 32
50
88
48
78
54
88
Po usunięciu
18
Przywracanie zbalansowania po usunięciu
Niech z będzie pierwszym „niezbalansowanym” węzłem, na który
natrafiamy idąc od w. Niech y będzie dzieckiem z o większej wysokości,
a x jego dzieckiem o większej wysokości.
Przeprowadzamy przebudowę drzewa w x , tak aby przywrócić
zbalansowanie w z (węzły a,b,c mają być w porządku inorder).
Ponieważ operacja taka może zachwiać balans w węźle powyżej musimy sprawdzać zbalansowanie drzewa powyżej (aż do korzenia)
a=z
w
62
44
17
50
48
c=x
78
54
44
b=y
62
88
17
78
50
48
88
54
19
Złożoność obliczeniowa operacji na drzewach AVL
Pojedyncza przebudowa zabiera czas O(1)
– Jeśli korzystamy ze struktury drzewa binarnego (tylko 1 lub 2 rotacje)
Wyszukiwanie zajmuje O(log n)
– Wysokość drzewa wynosi O(log n), nie potrzeba przebudowywać
drzewa
Wstawianie zajmuje O(log n)
– Odnalezienie miejsca O(log n)
– Przebudowa drzewa O(log n) – ze względu na wysokość drzewa
Usuwanie - O(log n)
– Odnalezienie zabiera czas O(log n)
– Naprawa drzewa O(log n) – ze względu na wysokość drzewa
20
Drzewa 2-3-4
9
2 5 7
10 14
21
Drzewa poszukiwań o wielu drogach
Drzewem poszukiwań o wielu drogach (B-drzewem) nazywamy
uporządkowane drzewo o następujących cechach:
– Każdy węzeł wewnętrzny posiada co najmniej 2 potomków i
przechowuje d −1 elementów-kluczy (ki, oi), gdzie d jest ilością
potomków węzła
– Dla każdego węzła o potomkach v1 v2 … vd przechowującego klucze k1
k2 … kd−1
• Klucze w poddrzewie v1 są mniejsze od k1
• Klucze w poddrzewie vi są pomiędzy ki−1 i ki (i = 2, …, d − 1)
• Klucze w poddrzewie vd są większe od kd−1
– Liście nie przechowują kluczy
11
2 6 8
24
15
27
32
30
22
Przechodzenie InOrder w drzewach o wielu drogach
Możliwe jest rozszerzenie notacji odwiedzania węzłów InOrder z
drzew binarnych na drzewa o wielu drogach
Odwiedzamy element (ki, oi) w węźle v pomiędzy rekursywnymi
odwiedzinami poddrzew v o korzeniu w vi i vi + 1
Odwiedzane węzły w tak zdefiniowanym porządku InOrder są
uporządkowane rosnąco
11
24
8
2 6 8
2
4
12
15
6
27
32
14
10
18
30
1
3
5
7
9
11
13
19
16
15
17
23
Poszukiwanie w drzewach o wielu drogach
Podobnie do poszukiwania w drzewie BST
Dla każdego węzła wewnętrznego o potomkach v1 v2 … vd o kluczach
k1 k2 … kd−−1:
– k = ki (i = 1, …, d − 1):poszukiwanie zakończone sukcesem
– k < k1: poszukiwanie kontynuujemy w poddrzewie v1
– ki−1 < k < ki (i = 2, …, d − 1): poszukiwanie kontynuujemy w
poddrzewie vi
– k > kd−1: poszukiwania kontynuujemy w poddrzewie vd
Dotarcie do liścia kończy poszukiwania (porażka)
Przykład : odszukujemy klucza 30
11
2 6 8
24
15
27
32
30
24
Drzewa 2-3-4
Drzewa 2-3-4 – nazywane też (2,4) – są drzewami poszukiwań o
wielu drogach o następujących własnościach
– własność ilości potomków: każdy węzeł wewnętrzny ma co
najwyżej 4 potomków
– własność wysokości: wszystkie liście mają tę samą wysokość
W zależności od ilości potomków, wewnętrzne węzły będziemy
nazywać 2-węzłami, 3-węzłami i 4-węzłami
10 15 24
2 8
12
18
27
32
25
Wysokość w drzewach 2-3-4
Twierdzenie: Drzewo 2-3-4 przechowujące n elementów ma wysokość O(log n)
dowód:
– niech h będzie wysokością drzewa 2-3-4 o n elementach
– ponieważ mamy co najmniej 2i elementów na poziomie i = 0, … , h − 1 i nie ma
elementów ma poziomie h, więc
n ≥ 1 + 2 + 4 + … + 2h−1 = 2h − 1
– stąd, h ≤ log (n + 1)
Wyszukiwanie w drzewie 2-3-4 o n elementach zajmuje czas O(log n)
poziom elementy
0
1
1
2
h−1
2h−1
h
0
26
Wstawianie
Nowy element (k, o) wstawiamy do węzła v – ostatniego wewnętrznego
węzła, przez który przechodziliśmy poszukując k
– Nie psujemy własności wysokości drzewa
– Możemy spowodować przepełnienie węzła (v może stać się 5-węzłem)
Przykład: wstawianie 30 powoduje przepełnienie
10 15 24
2 8
12
18
10 15 24
2 8
12
18
v
27 32 35
v
27 30 32 35
27
Przepełnienie i rozdzielanie węzła
Problem przepełnienia można rozwiązać przez podział węzła v:
– niech v1 … v5 będą potomkami v i k1 … k4 będą kluczami w v
– węzeł v zastępujemy 2 węzłami v' i v"
• v' jest 3-węzłem o kluczach k1 k2 i potomkach v1 v2 v3
• v" jest 2-węzłem o kluczach k4 i potomkach v4 v5
– klucz k3 jest wstawiany do rodzica u węzła v (to może tworzyć nowy korzeń)
Przepełnienie może teraz nastąpić w węźle u
u
u
15 24 32
15 24
v
12
18
27 30 32 35
v1 v2 v3 v4 v5
v'
12
18
27 30
v1 v2 v3 v4
v"
35
v5
28
Analiza wstawiania
Algorytm insertItem(k, o)
1. Odszukujemy klucz k w celu
zlokalizowania węzła do
wstawienia wartości v
2. Dodajemy nowy element (k, o) w
węźle v
3. while overflow(v)
if isRoot(v)
twórz nowy pusty korzeń nad v
v ← split(v)
Niech T będzie drzewem 2-3-4 o n
elementach
– T ma wysokość O(log n)
– krok 1 zajmuje czas O(log n),
ponieważ odwiedzamy O(log n)
węzłów
– krok 2 zajmuje czas O(1)
– krok 3 zabiera O(log n) czasu,
ponieważ każde rozdzielanie
zabiera O(1) i możemy mieć
O(log n) takich operacji
Stąd wstawianie do drzewa 2-3-4
zajmuje czas O(log n)
29
Usuwanie
Rozważania na temat usuwania można sprowadzić tylko do przypadku
usuwania wartości z węzła posiadającego jedynie potomków liście
W przeciwnym razie (węzły wewnętrzne) zastępujemy element kolejnym w
porządku inorder (następnikiem – jego lewe dziecko musi być liściem)
Przykład: usuwanie 24 – zastępujemy 24 przez następnik w porządku
inorder - 27
10 15 24
2 8
12
18
27 32 35
10 15 27
2 8
12
18
32 35
30
Niedobór i łączenie
Usunięcie elementu z węzła v może spowodować niedobór - v może
stać się 1-węzłem (0 klucz, 1 potomek)
Dla obsługi tej sytuacji należy połączyć v z rodzicem u, rozpatrzmy
dwa przypadki
przypadek 1: sąsiedni brat v jest 2-węzłem
– operacja łączenia: łączymy v z bratem w i przenosimy element z u do
połączonego węzła v'
– po połączeniu, niedobór może nastąpić w węźle powyżej (u)
u
u
9 14
w
2 5 7
10
9
v'
v
2 5 7
10 14
31
Niedobór i łączenie
przypadek 2: sąsiedni brat w węzła v jest 3-węzłem lub 4-węzłem
– przenosimy:
1. potomka w do v
2. element z u do v
3. element z w do u
– po przeniesieniu nie występują przepełnienia
u
u
4 9
4 8
w
2
6 8
v
w
2
6
v
9
32
Analiza usuwania
Niech T będzie drzewem 2-3-4 o n elementach
– wysokość T wynosi O(log n)
Operacja usuwania:
– odwiedzamy O(log n) węzłów aby odszukać węzeł, z którego
usuwamy element
– obsługa niedoborów może prowadzić do wykonania serii O(log n)
łączeń węzłów (przyp. 1) oraz jednego przesuwania (przyp. 2)
– każde łączenie zajmuje O(1)
Stąd operacja usuwania w drzewie 2-3-4 zajmuje czas O(log n)
33

Podobne dokumenty