LAB 11
B4M33PAL - Ing. David Pařil
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:
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).
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:
$$O(\sum_{úrovně} \text{délka úrovně}) = O(k\cdot N) = O(N)$$
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:
x = head.forward[0] (první uzel na spodní úrovni)x nastavím head.forward[i] = x.forward[i]
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)\)
Navrhněte efektivní operaci decreaseKey ve skip listu.
Řešení
Předpoklad: známe ukazatel na uzel x (search v \(O(\log n)\))
x.key = new_key
insert(x)
Celá operace decreaseKey je tedy v očekávaném čase \(O (\log N)\)
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
\(\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
\(\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)\)
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í):
Pro N uzlů:
$$\mathbb{E}[\sum_{i=1}^{N}H_i]= N\frac{1}{1-p} = O(N)$$
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)\)?
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
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ů
_
_
_
_
_
_
_
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.
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:
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
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?