Obsah / Utility / RBTREE / Procházení RB-stromem
Zdrojový kód: INCLUDE\UTIL\RBTREE.INC, UTIL\RBTREE.ASM
Procházení RB-stromem
Při procházení RB-stromem využíváme tříděný seznam položek spojený popisovači LIST.
|
Funkce RBTreeFirst vyhledá první uzel ve stromu, tedy položku, která je na začátku setříděného seznamu. Vstupním parametrem funkce je v registru EDX ukazatel na kořen stromu, výstupním parametrem je v registru EBX ukazatel na první položku stromu (nebo nula při chybě) a příznak chyby CF indikující, že žádná položka nebyla nalezena (tj. seznam je prázdný).
Z proměnné LIST_Next je do registru EBX načten ukazatel na první položku ve stromu. Testem příznaku RB_ROOT položky lze otestovat, zda se jedná o platnou položku. Jedná-li se opět o kořen stromu, je seznam položek prázdný. V tom případě se obsah registru EBX vynuluje a nastaví se příznak chyby CF.
|
Funkce RBTreeLast vyhledá poslední uzel ve stromu, tedy položku, která je na konci setříděného seznamu. Vstupním parametrem funkce je v registru EDX ukazatel na kořen stromu, výstupním parametrem je v registru EBX ukazatel na poslední položku stromu (nebo nula při chybě) a příznak chyby CF indikující, že žádná položka nebyla nalezena (tj. seznam je prázdný).
Z proměnné LIST_Prev je do registru EBX načten ukazatel na poslední položku ve stromu. Testem příznaku RB_ROOT položky lze otestovat, zda se jedná o platnou položku. Jedná-li se opět o kořen stromu, je seznam položek prázdný. V tom případě se obsah registru EBX vynuluje a nastaví se příznak chyby CF.
|
Funkce RBTreeNext vyhledá následující uzel ve stromu, tedy položku, která následuje v setříděném seznamu za aktuální položkou. Vstupním parametrem funkce je v registru EBX ukazatel na aktuální položku, výstupním parametrem je v registru EBX ukazatel na další položku stromu (nebo nula při chybě) a příznak chyby CF indikující, že další položka nebyla nalezena (tj. položka je poslední položkou seznamu).
Z proměnné LIST_Next je do registru EBX načten ukazatel na další položku ve stromu. Testem příznaku RB_ROOT položky lze otestovat, zda se jedná o platnou položku. Jedná-li se opět o kořen stromu, nenásleduje další položka. V tom případě se obsah registru EBX vynuluje a nastaví se příznak chyby CF.
|
Funkce RBTreePrev vyhledá předešlý uzel ve stromu, tedy položku, která předchází v setříděném seznamu před aktuální položkou. Vstupním parametrem funkce je v registru EBX ukazatel na aktuální položku, výstupním parametrem je v registru EBX ukazatel na předcházející položku stromu (nebo nula při chybě) a příznak chyby CF indikující, že předešlá položka nebyla nalezena (tj. položka je první položkou seznamu).
Z proměnné LIST_Prev je do registru EBX načten ukazatel na předešlou položku ve stromu. Testem příznaku RB_ROOT položky lze otestovat, zda se jedná o platnou položku. Jedná-li se opět o kořen stromu, nenásleduje předešlá položka. V tom případě se obsah registru EBX vynuluje a nastaví se příznak chyby CF.
|
Funkce RBTreeIndex vyhledá uzel ve stromu podle indexu, tedy vyhledá položku, která se v setříděném seznamu nachází na určité pozici seznamu. Vstupními parametry funkce jsou v registru EAX absolutní index požadované položky a v registru EDX ukazatel na kořen stromu. Výstupním parametrem je v registru EBX ukazatel na hledanou položku stromu (nebo nula při chybě) a příznak chyby CF indikující, že položka s daným indexem nebyla nalezena.
Na začátku funkce je ověřena platnost požadovaného indexu položky. Do registru ECX je z kořene stromu načten počet položek a porovnán s požadovaným indexem v registru EAX. Má-li požadovaný index stejnou nebo větší hodnotu než je počet položek ve stromu, funkce se ukončí s nastaveným příznakem chyby CF a s vynulovaným registrem EBX.
Pro zrychlení vyhledávání bude položka hledána buď od začátku seznamu nebo od jeho konce v závislosti na tom, kterému konci seznamu je blíže. Porovnáním požadovaného indexu v EAX s polovinou počtu položek v ECX se rozliší, zda bude výhodnější hledání od začátku (EAX < ECX/2) nebo od konce (EAX >= ECX/2).
Při hledání položky od začátku seznamu se do registru ECX uloží index požadované položky a z kořene stromu v registru EDX se načte první položka seznamu. Není třeba kontrolovat platnost položky, protože platnost indexu položky byla ověřena na začátku funkce. Je-li požadována první položka seznamu (index = 0), funkce se úspěšně ukončí. Jinak pokračuje procházením seznamu položek pomocí ukazatelů na další položky, až nalistuje hledanou položku.
Při hledání položky od konce seznamu se do registru ECX připraví počet položek seznamu a odečtením požadovaného indexu v EAX a dekrementací údaje se vypočte relativní index položky vzhledem ke konci seznamu. Z kořene stromu v registru EDX se načte poslední položka seznamu. Není třeba kontrolovat platnost položky, protože platnost indexu položky byla ověřena na začátku funkce. Je-li požadována poslední položka seznamu (index = počet - 1), funkce se úspěšně ukončí. Jinak pokračuje procházením seznamu položek pomocí ukazatelů na předešlé položky, až nalistuje hledanou položku.
|
Funkce RBTreeIndexRel vyhledá položku setříděného seznamu relativně k aktuální položce (jedná se tedy o posun o daný počet položek). Vstupem funkce je v registru EAX relativní index hledané položky (kladné nebo záporné číslo) a v registru EBX ukazatel na aktuální položku. Výstupem funkce je v registru EBX ukazatel na hledanou položku stromu (nebo nula při chybě) a příznak chyby CF indikující, že položka nebyla nalezena.
Na začátku funkce je testem hodnoty požadovaného indexu v EAX rozlišeno, zda se jedná o hledání směrem nahoru (EAX je kladné), dolů (EAX je záporné) nebo se jedná o tuto položku (EAX = 0, funkce se úspěšně ukončí).
Jedná-li se o hledání směrem nahoru (k vyšším indexům), posune se ukazatel pomocí funkce RBTreeNext o daný počet položek směrem vpřed. Je-li nalezen konec seznamu, funkce se předčasně ukončí s nastaveným příznakem chyby a s vynulovaným registrem EBX.
Jedná-li se o hledání směrem dolů (k nižším indexům), opraví se znaménko relativního indexu v registru ECX a ukazatel se posune pomocí funkce RBTreePrev o daný počet položek směrem zpět. Je-li nalezen začátek seznamu, funkce se předčasně ukončí s nastaveným příznakem chyby a s vynulovaným registrem EBX.
|
Funkce RBTreeVerify slouží k ověření, zda položka patří do daného RB-stromu. Vstupními parametry funkce jsou v registru EBX ukazatel na hledanou položku a v registru EDX ukazatel na kořen stromu. Je-li položka ve stromu nalezena, navrátí funkce v registru EAX index položky a vynuluje příznak CF. Není-li nalezena, navrátí index položky -1 a nastavený příznak chyby CF.
Funkce si připraví do registru ECX adresu položky k vyhledání, do registru EAX si připraví index poslední položky seznamu a pomocí funkce RBTreeLast zjistí ukazatel na poslední položku seznamu. Neexistuje-li poslední položka seznamu (tj. seznam je prázdný), funkce se ukončí s nastaveným příznakem chyby a s registrem EAX nastaveným na -1 (protože počet položek v seznamu = 0).
Během vyhledávání položek je adresa každé položky porovnána, zda se jedná o hledanou položku, v tom případě je funkce ukončena s vynulovaným příznakem chyby, registr EAX obsahuje index položky. Jinak je index položky dekrementován a pomocí funkce RBTreePrev je vyhledána předcházející položka seznamu. Není-li nalezena žádná další předešlá položka (tj. dosáhlo se začátku seznamu), je funkce ukončena s příznakem chyby CF, registr EAX obsahuje hodnotu -1 (ukazatel indexu podtekl pod 0).
|
Funkce RBTreeGetInx slouží k zjištění indexu položky v seznamu a k nalezení kořene stromu. Na rozdíl od předešlé funkce musí být položka seznamu začleněná do nějakého platného RB-stromu. Vstupním parametrem funkce je v registru EBX ukazatel na hledanou položku. Výstupním parametrem je v registru EAX index položky ve stromu a v registru EDX ukazatel na kořen stromu. Vzhledem k tomu, že položka musí být začleněná do platného stromu, není funkcí navracen žádný chybový kód.
Funkce přednastaví v registru EAX ukazatel indexu položky na hodnotu -1 a do registru EDX si připraví ukazatel na aktuální položku. Poté prochází seznam tříděných položek směrem k počátku seznamu, přičemž postupně inkrementuje index položky, a to do té doby, než narazí na kořen stromu (rozpozná ho podle nastaveného příznaku RB_ROOT), jehož adresu navrátí v registru EDX.
Obsah / Utility / RBTREE / Procházení RB-stromem