Skip list, Vyhledávací stromy: B, B+
LAB 11
B4M33PAL - Ing. David Pařil
Příklad
Skip list 101
Sestavte skip list, který je nejprve prázdný a dále do něj vkládáte dané klíče v uvedeném pořadí.
Číslo za klíčem uvádí úroveň (level) klíče, tj. kolikrát byla hozena mince, než padl rub (včetně rubu).
16 | 3
23 | 2
18 | 2
5 | 2
15 | 1
19 | 1
33 | 1
11 | 2
21 | 2
4 | 1
22 | 2
6 | 2
17 | 4
10 | 1
9 | 1
28 | 4
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
16 | 3
23 | 2
18 | 2
5 | 2
15 | 1
19 | 1
33 | 1
11 | 2
21 | 2
4 | 1
22 | 2
6 | 2
17 | 4
10 | 1
9 | 1
28 | 4
Řešení
Coin flips kód: 1101010100001010010101110001110
Sekvence:
Příklad
Mergování skiplistů
Mějme dva skip listy délky N.
Máme navrhnout efektivní algoritmus, který tyto dva skip listy spojí do jediného skip listu délky 2N.
Jaká bude jeho asymptotická složitost?
Skip list A:
Řešení:
Skip list B:
10
7
7
4
4
4
1
13
13
16
2
2
3
8
8
12
12
12
14
15
15
Skip list A:
Řešení:
Skip list B:
10
7
7
4
4
4
1
13
13
16
2
2
3
8
8
12
12
12
14
15
15
Skip list A:
Řešení:
Skip list B:
1
2
2
3
8
8
12
12
12
14
15
15
10
7
7
4
4
4
13
13
16
Skip list A:
Řešení:
Skip list B:
1
2
2
3
8
8
12
12
12
14
15
15
10
7
7
4
4
4
13
13
16
Skip list A:
Řešení:
Skip list B:
1
2
2
3
8
8
12
12
12
14
15
15
10
7
7
4
4
4
13
13
16
Skip list A:
Řešení:
Skip list B:
1
2
2
3
8
8
12
12
12
14
15
15
10
7
7
4
4
4
13
13
16
Skip list A:
Řešení:
Skip list B:
1
2
2
3
8
8
12
12
12
14
15
15
10
7
7
4
4
4
13
13
16
Skip list A:
Řešení:
Skip list B:
1
2
2
3
8
8
12
12
12
14
15
15
10
7
7
4
4
4
13
13
16
Skip list A:
Řešení:
Skip list B:
1
2
2
3
8
8
12
12
12
14
15
15
10
7
7
4
4
4
13
13
16
Skip list A:
Řešení:
Skip list B:
1
2
2
3
8
8
12
12
12
14
15
15
10
7
7
4
4
4
13
13
16
Skip list A:
Řešení:
Skip list B:
1
2
2
3
8
8
12
12
12
14
15
15
10
7
7
4
4
4
13
13
16
Skip list A:
Řešení:
Skip list B:
1
2
2
3
8
8
12
12
12
14
15
15
10
7
7
4
4
4
13
13
16
Skip list A:
Řešení:
Skip list B:
1
2
2
3
8
8
12
12
12
14
15
15
10
7
7
4
4
4
13
13
16
Řešení
Mějme dva skip listy \(A\) a \(B\) délky \(N\). Nechť \(A[i]\) a \(B[i]\) značí \(i\)-tý prvek v \(A\) a \(B\). Předpokládejme, že \(A[1] ≤ B[1]\) (jinak si seznamy A a B prohodíme).
Použijeme dva indexy \(p_A\) a \(p_B\), které ukazují na prvky v \(A\) a \(B\); na začátku nastavíme \(p_A = 1\), \(p_B = 1\).
Pak opakujeme:
-
pokud \(A[p_A+1] < B[p_B]\), zvětšíme \(p_A\) o \(1\),
-
jinak vložíme prvek \(B[p_B]\) do \(A\) hned za prvek \(A[p_A]\) a zvýšíme \(p_A\) i \(p_B\) o \(1\) (tedy \(p_A\) bude ukazovat na nově vložený prvek).
Tento postup opakujeme, dokud nejsou všechny prvky z \(B\) vloženy do \(A\). Algoritmus běží v čase O(N).
Příklad
Reverse skiplistu
Je možno obrátit pořadí prvků ve skip listu (z vzestupného uspořádání klíčů přejít na sestupné) v čase asymptoticky menším než \(O(N \cdot \log(N))\)?
Řešení
Nemusíme přebudovávat celý skip list v novém pořadí, ale jen:
- pro každou úroveň vzít její jednosměrný seznam a obrátit ho
- upravit ukazatele z hlavičkového uzlu na nový první prvek na dané úrovni
- V porovnání klíčů jen prohodit znaménko (\( X < Y \rightarrow X > Y\))
$$O(\sum_{úrovně} \text{délka úrovně}) = O(k\cdot N) = O(N)$$
Příklad
Extractmin
Formulujte operaci extractMin ve skip listu a popište, jak lze potom skip list použít jako prioritní frontu.
Bude efektivita jednotlivých operací asymptoticky srovnatelná s binární haldou?
Řešení
Minimum ve skip listu je vždy první prvek za hlavou na nejnižší úrovni!
1
2
2
3
8
8
12
12
12
14
15
15
10
7
7
4
4
4
13
13
16
1
1
1
1
2
2
3
8
8
12
12
12
14
15
15
10
7
7
4
4
4
13
13
16
1
1
1
Postup:
- Získám
x = head.forward[0](první uzel na spodní úrovni) - Pro všechny úrovně
xnastavímhead.forward[i] = x.forward[i] - Případně snížíme celkovou výšku skip listu
- Vrátíme klíč uzlu
x
10
7
7
4
4
4
1
Skip list
Binomiální halda
Insert:
FindMin:
ExtractMin:
Insert:
FindMin:
ExtractMin:
\(O(\log N)\)
\(O(1)\)
\(O(1)\)
\(O(\log N)\)
\(O(1)\)
\(O(\log N)\)
Očekávané - v nejhorším čase až \(O(\log N)\)
Příklad
DecreaseKey
Navrhněte efektivní operaci decreaseKey ve skip listu.
Řešení
Předpoklad: známe ukazatel na uzel x (search v \(O(\log n)\))
- Smazání
Standardní delete ve skip listu \(\rightarrow\) \(O(\log n)\) - Změna klíče
Nastavímex.key = new_key - Znovuvložení uzlu
Uděláme standardníinsert(x)- search(new_key)
- nastavení hran mezi uzly
Očekávaná složitost \(O (\log n)\)
Celá operace decreaseKey je tedy v očekávaném čase \(O (\log N)\)
Příklad
Asymptotická složitost přesyceného skip listu
Při implementaci skip listu se stalo, že hodnota level každého uzlu v operaci Insert je určena jako náhodné číslo z intervalu \(\langle 1, \log_2 N \rangle\), přičemž se jedná o rovnoměrné rozložení a \(N\) je vždy aktuální počet prvků v seznamu.
Odhadněte (pro velké \(N\)), nakolik se zhorší asymptotická složitost operací Find/Insert/Delete v tomto skip listu.
Řešení
4
3
3
2
1
8
7
6
5
1
1
5
7
5
4
3
2
2
1
8
7
6
5
1
1
4
4
5
7
7
8
Klasický
Skip List
Modifikovaný
Skip List
\(\mathbb{P}(level \geq k) = 2^{-(k-1)}\)
\(\mathbb{P}(level \geq k) = \frac {\log N - k + 1}{\log N}\)
4
3
3
2
1
8
7
6
5
1
1
5
7
5
4
3
2
2
1
8
7
6
5
1
1
4
4
5
7
7
8
Klasický
Skip List
Modifikovaný
Skip List
\(\mathbb{P}(level \geq k) = 2^{-(k-1)}\)
\(\mathbb{P}(level \geq k) = \frac {\log N - k + 1}{\log N}\)
Na nejvyšším levelu je zhruba \(\frac {N}{\log N}\) prvků.
Pst propadu na nižší úroveň je ekvivalentní na všech (\(log(N)\)) úrovních.
Operace Find má tím pádem očekávanou složitost \(O(\frac{N \cdot \log N}{\log N}) = O(N)\)
Operace Insert i Delete využívají Find, takže mají stejné \(O(N)\)
Příklad
Akademický Spor v zoo
Profesor T-rex tvrdí, že v průměrném případě ve skip listu o délce \(N\) je součet všech hodnot prvek.level úměrný hodnotě \(N \cdot \log(N)\).
Profesor Tučňák tvrdí, že tento součet je úměrný pouze hodnotě \(N\).
Profesor Kůň tvrdí, že mohou nastávat oba případy a že záleží na datech.
Rozhodněte akademický spor.



Řešení
Ve standardním skip listu se level určuje náhodně (házením mincí):
- pst, že má alespoň level \(k\) je \(p^{k-1}\), kde \(p = \frac 1 2\) typicky
- střední hodnota / očekávaná výška uzlu:
$$\mathbb{E}[H] = \sum_{k=1}^{\infty} p^{k-1} = \frac{1}{1-p}$$
Pro N uzlů:
$$\mathbb{E}[\sum_{i=1}^{N}H_i]= N\frac{1}{1-p} = O(N)$$

Příklad
TODO
Mějme jediný skip list délky \(N\).
Máme navrhnout efektivní algoritmus, který tento skip list rozdělí na dva, přičemž první bude obsahovat pouze klíče liché hodnoty a druhý pouze klíče sudé hodnoty. Lze úlohu splnit v čase \(O(N)\)?
Příklad
B-stromy
Do B-stromu znázorněného na levém resp. pravém obrázku vložíme postupně klíče 14, 10, resp. 7, 5.
Jaké klíče pak bude obsahovat kořen stromu?
8
15
11
_
16
20
2
6
8
25
19
21
30
40
3
_
Řešení
8
15
11
_
16
20
2
6
Start
Řešení
8
15
11
14
16
20
2
6
Start
Vložení 14
Řešení
8
15
11
14
16
20
2
6
Start
Vložení 14
Vložení 10
10
Řešení
8
15
11
14
16
20
2
6
Start
Vložení 14
Vložení 10
10
Split + propagace 11 do kořene
Řešení
8
15
11
14
16
20
2
6
Start
Vložení 14
Vložení 10
10
Split + propagace 11 do kořene
Split kořene
V kořenu bude číslo 11
8
25
19
21
30
40
3
_
Řešení
Start
8
25
19
21
30
40
3
7
Řešení
Start
Vložení 7
8
25
19
21
30
40
3
7
Řešení
Start
Vložení 7
Vložení 5
5
8
25
19
21
30
40
3
7
Řešení
Start
Vložení 7
Vložení 5
5
Split + propagace 5 do kořene
8
25
19
21
30
40
3
7
Řešení
Start
Vložení 7
Vložení 5
5
Split + propagace 5 do kořene
Split kořene
V kořenu bude číslo 8
Příklad
Neizomorfní B-stromy
Dva prázdné B-stromy řádu 1 (max. 2 klíče v uzlu) jsou izomorfní.
Neprázdný B-strom \(B_1\) řádu 1 s kořenem \(K_1\) je izomorfní s neprázdným B-stromem \(B_2\) řádu 1 s kořenem \(K_2\) právě tehdy, když zároveň platí 1. a 2.:
1. \(K_1\) obsahuje stejný počet klíčů jako \(K_2\)
2. Levý podstrom \(K_1\) je izomorfní s levým podstromem \(K_2\), pravý podstrom \(K_1\) je izomorfní s pravým podstromem \(K_2\) a prostřední podstrom \(K_1\), pokud existuje, je izomorfní s prostředním podstromem \(K_2\).
Určete počet navzájem neizomorfních B-stromů řádu 1 s:
A) 0 B) 1 C) 3 D) 4 E) 7 uzly.
Řešení - 0 uzlů
Prázdný strom je jen jeden...
¯\_(ツ)_/¯
Řešení - 1 uzel
Strom tvoří jen kořen (list)
Celkem tedy 2 možnosti (1 klíč nebo 2 klíče v uzlu)
_
_
_
Řešení - 3 uzly
Kořen může mít jenom 1 klíč (2 listy)
\(\rightarrow\) 2 klíče by znamenaly 3 listy \(\rightarrow\) 4 uzly
Kostra má 2 listy, každý může mít 1/2 klíče: \(2^2 = 4\) možnosti
_
_
_
_
_
_
_
_
_
_
_
_
_
_
_
_
Řešení - 7 uzlů
Existuje pouze jediná kostra, která generuje 7 uzlů:
Dolní 4 listy generují navíc až \(2^4 = 16\) možných stromů
_
_
_
_
_
_
_
Příklad
TODO
Formulujte rekurentní postup, jímž lze obecně určit počet navzájem neizomorfních B-stromů řádu 1, použijte definici izomorfizmu z předchozí úlohy.
Příklad
B-stromy
B-strom je řádu \(k\), pokud každý jeho uzel, kromě kořene, musí obsahovat alespoň \(k\) klíčů a zároveň může obsahovat nejvýše \(2k\) klíčů.
Vybudujte B-strom řádu \(1\) tak, že do prázdného stromu vložíte v uvedeném pořadí klíče
Dále tento strom zrušte, a to tak, že jednotlivé klíče klíče odstraníte v pořadí
Nakreslete strom po každé operaci Insert a Delete.
25
13
37
40
20
22
13
25
40
22
20
37
32
32
Řešení
Přidat:
25
13
37
40
20
22
13
25
40
22
20
37
32
32
Odebrat:
Příklad
B+stromy
Vybudujte B+ strom řádu 1 tak, že do prázdného stromu vložíte v uvedeném pořadí klíče
Dále tento strom zrušte, a to tak, že jednotlivé klíče klíče odstraníte v pořadí
Nakreslete strom po každé operaci Insert a Delete.
32
18
31
59
20
23
24
36
60
58
15
57
51
17
16
26
42
21
43
12
23
31
26
15
24
42
17
36
20
43
16
32
18
59
21
51
60
12
58
57
Řešení
Přidat:
Odebrat:
32
18
31
59
20
23
24
36
60
58
15
57
51
17
16
26
42
21
43
12
23
31
26
15
24
42
17
36
20
43
16
32
18
59
21
51
60
12
58
57
Příklad
TODO
Je dán a) B-strom b) B+ strom. Strom je řádu 10 a máme do něj umístit 100 000 klíčů. Jaký je maximální a minimální možný počet uzlů tohoto stromu? Jaká je maximální a minimální možná hloubka tohoto stromu?
Na
Viděnou
Za týden :)
PAR_Lab11
By David Pařil
PAR_Lab11
- 2