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:

  1. Získám x = head.forward[0] (první uzel na spodní úrovni)
  2. Pro všechny úrovně x nastavím head.forward[i] = x.forward[i]
  3. Případně snížíme celkovou výšku skip listu
  4. 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)\))

  1.  Smazání
    Standardní delete ve skip listu \(\rightarrow\) \(O(\log n)\)
  2. Změna klíče
    Nastavíme x.key = new_key
  3. 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 :)