Binární vyhledávací stromy

Když potřebujeme v paměti nějak reprezentovat data o kterých víme že:

  1. 1) půjdou očíslovat
  2. 2) nevíme kolik jich přesně bude
  3. 3) budeme v nich často vyhledávat, vkládat nové a odebírat existující prvky

Je dobrý nápad použít něco lepšího než spojový seznam. Na cvičení jsme se zabývali datovou strukturou, známou jako binární vyhledávací strom. Tato struktura využívá podobně jako binární halda fakt, že vyvážený binární strom má logaritmickou hloubku vzhledem k počtu prvků. To v praxi znamená, že operaci vyhledání prvku je možné implementovat tak, aby měla logaritmickou složitost.

Předpokládejme, že v Pascalu reprezentujeme uzel stromu například takto:

PNode = ^TNode;
TNode = record
	 key: longint;
	 left: PNode;
	 right: PNode;
        end;

Následující pravidla zajistí, že bude fungovat vyhledávání podle hodnoty key:

  1. ☛ Pro každý vnitřní uzel X: PNode; (kořen nevyjímaje) platí:
    (X^.left^.key < X^.key) and (X^.right^.key > X^.key)
    a také:
    (X^.left <> nil) or (X^.right <> nil)
  2. ☛ Pro každý list L: PNode; platí:
    (L^.left = nil) and (L^.right nil)

Poznámka:

BVS má svoje nevýhody - může se stát, že nebude vyvážený a tím se ztratí výhoda logaritmické hloubky. Tento problém řeší například AVL-stromy nebo RB-stromy. Obě zmíněné datové struktury z BVS vychází - pouze přidávají dodatečná vyvažovací pravidla využívající dodatečnou informaci v uzlech za tímto učelem tam uloženou.

Operace na BVS

Na cvičení jsme společně naprogramovali funkce:

  1. function Find(node : PNode; k : Integer) : PNode;

    Tato funkce dostane na vstupu uzel, ve kterém má začít vyhledávat a vrací odkaz na rodiče hledaného prvku. Pokud prvek ve stromě není, vrací ukazatel na uzel, jehož synem by měl hledaný prvek podle pravidel BVS být. Je třeba testovat, jestli výsledek není nil - toto nastane vždy když vyhledáváme v prázdném stromě.

  2. function Insert(var node : PNode; k : Integer) : PNode;

    Při vkládání prvku je výhodné využít výše uvedenou funkci Find k nalezení vhodného místa pro vložení. Pokud prvek k už ve stromě existuje, nic se nestane. Jinak je třeba alokovat nový uzel a připojit ho na správné místo.

Domácí úkol

Skvělou příležitost k procvičení práce s binárními vyhledávacími stromy skýtá uloha Banka BVS.