Datové struktury založené na stromech

Editovat
Note

Stromové datové struktury (binární vyhledávací stromy, B-stromy, červeno-černé stromy, haldy), související operace a jejich složitost. Typické implementace, příklady použití.

IB002

Warning
Obrázky v této otázce kreslené rukou byly sprostě ukradeny Dominice Krejčí z https://github.com/Krejdom/school_notes. Snad jen dočasně.

Strom je abstraktní datová struktura, o které se dá uvažovat jako o množině uzlů, které mají právě jednoho rodiče a konečný počet dětí. Výjimkou je kořen, který nemá rodiče. Hodnotám v uzlech se říká klíče.

Binární strom

Strom, kde každý uzel má nejvýše dvě děti.

Výška uzlu

Počet hran nejdelší cesty z do některého z poddaných listů.

Binární vyhledávací strom (BVS)

Binární strom, kde pro každý uzel platí

  • klíče uzlů v jeho levém podstromě jsou menší nebo rovny klíči uzlu ,

  • klíče uzlů v jeho pravém podstromě jsou větší než klíč uzlu .

Je teoretickým základem pro složitejší stromové struktury.

Příklad
Diagram
Inorder průchod
def inorder(node):
    inorder(node.left)
    print(node.key)
    inorder(node.right)
Preorder průchod
def preorder(node):
    print(node.key)
    preorder(node.left)
    preorder(node.right)
Postorder průchod
def postorder(node):
    postorder(node.left)
    postorder(node.right)
    print(node)
Následník uzlu

Je uzel obsahující nejmenší klíč větší než n.key.

Předchůdce uzlu

Je uzel obsahující největší klíč menší než n.key.

Úplný binární strom

Všechna jeho patra, kromě nejnižšího jsou zaplňena. V nejnižším patře jsou listy nasoukané vlevo.

AVL-strom

BVS, kde délka nejdelší větve levého a pravého podstromu každého uzlu se liší nejvýše o 1.

Implementace

Každý uzel má v paměti vlastní strukturu/objekt a obsahuje:

  • klíč (hodnotu),

  • ukazatel na levého syna,

  • ukazatel na pravého syna.

Binární vyhledávání

Porovnáváme hodnotu s klíčem a jdeme buď doleva nebo doprava.

Minimum a maximum

Jde úplně vlevo pro minimum, úplně vpravo pro maximum.

Následník

Pokud má uzel pravý podstrom, následník je jeho minimem. Pokud nemá pravý podstrom, hledáme prvního předka, v jehož levém podstromu se uzel nachází.

Insert

Binární vyhledávání, ale na prázdné místo dáme uzel.

Remove

Binární vyhledávání, ale nalezený uzel smažeme. Pokud měl děti, najdeme jeho následníka a dosadíme ho za smazaný uzel.

Halda (heap)

Strom splňující vlastnost haldy, t.j. klíč každého uzllu je větší než klíče jeho dětí. Kořen má největší klíč.

Používá se např. k implementaci prioritní fronty a v heap sortu.

Note
Z historických důvodů se slovem ,,halda'' označuje také kus paměti určený pro dynamickou alokaci. V dnešní době tam už souvislost, zdá se, není.
Binární halda

Úplný binární strom splňující vlastnost haldy.

Maximová halda

Kořen má největší klíč.

Minimová halda

Kořen má nejmenší klíč.

Heap sort

Vybudujeme haldu () a postupně z ní odstraňujeme kořen (), což vždy následuje oprava haldy (). Celková složitost je .

Implementace

Binární haldu lze implementovat pomocí pole:

  • Kořen je na indexu 1.

  • Levý syn uzlu je na .

  • Pravý syn uzlu je na .

Note
Indexuješ-li od nuly, pak je to a

Rodič uzlu se nachází na (při indexování od 1).

Červeno-černý strom

Binární vyhledávací strom, který ma uzly obarvené červenou nebo černou barvou a splňuje následující podmínky

  • kořen je černý,

  • listy neobsahují klíče (obsahují null) a jsou černé,

  • pokud je uzel červený, má černého rodiče,

  • pro každý uzel platí, že všechny cesty z něj do listu obsahují stejný počet černých uzlů.

Používá se k výpočtu ranku prvku (počet menších prvků zvýšený o jedna), při implementaci asociativní paměti a AVL-stromů.

Černá výška uzlu

Počet černých uzlů na cestě z do některého z poddaných listů . Pokud je černý, nepočítá se.

Každý uzel výšky má černou výšku alespoň .

Červeno-černý strom s vnitřními uzly má výšku nejvýše .

Implementace

Jako BVS, ale každý uzel obsahuje kromě klíče a ukazatelů na potomky také barvu a ukazatel na rodiče.

Rotace

Používájí se k opravě následků přidávání a odebírání uzlů.

i17 rotace
Insert

Uzel vložíme do stromu stejně jako do BVS a obarvíme ho červeně. A strom opravíme. Jelikož oprava má konstantní složitost, je složitost stejná jako u BVS, t.j. .

i17 oprava
Delete

Uzel ostraníme stejně jako u BVS. Navíc, pokud byl červený, tak se nic neděje, ale pokud byl černý a

  • měl jednoho syna, tak jeho syn zaujme jeho místo.

  • měl dva syny a jeden z nich je jeho následník, tak jeho místo zaujme syn-následník

  • měl dva syny a ani jeden z nich nebyl jeho následník, následník zaujme jeho místo a stane se otčímem obou synů. U původních dětí se řeší stejná situace jako tady.

    Následně opravíme barvy.

B-strom

B-strom stupně je strom, kde platí

  • každý uzel má nejvýše dětí,

  • každý vnitřní uzel (kromě kořene) má alespoň dětí,

  • kořen má alespoň 2 děti, pokud není listem,

  • vnitřní uzel s dětmi obsahuje klíčů,

  • všechny listy mají stejnou hloubku a jejich klíče jsou null.

Klíče ve vnitřních uzlech vymezují intervaly, do kterých spadají jejich postromy.

Note
V IB002 má B-strom nejméně dětí a nejvýše dětí. Hodnota je minimální stupeň stromu.

B-strom s klíči a minimálním stupněm má hloubku nejvýše .

Využívá se v databázích a je základem B+ stromu.

Plný uzel

dětí.

Implementace

Struktura/objekt reprezentující uzel v paměti obsahuje:

  • počet klíčů,

  • klíče v neklesajícím pořadí,

  • ukazatele na děti.

Vyhledávání

Analogické binárnímu vyhledávání.

Insert

Vyhledáváním najdeme uzel, kam by klíč měl patřit. Pokud je uzel plný, rozdělíme ho na dva. Pokud tím přeplníme rodiče, rozdělíme i rodiče, atd.

Preemptivní dělení

Optimalizace přístupu na disk. Pokud při průchodu stromem narazíme na plný uzel, pro jistotu ho rozdělíme.

Delete

Mazání probíhá vždy v listu. Pokud mazaný klíč není v listu, nahradíme ho za následníka, přesuneme ho do listu, a pak ho teprve smažeme.

Preemptivní slučování

Pokud narazíme na uzel, co má uzlů, zvýšíme počet přesunem vhodného klíče na .

Složitost základních operací

Struktura insert remove search max min next prev

Binární vyhledávací strom

Binární maximová halda

pro maximum

Červeno-černý strom

B-strom