TÉMATICKÝ OKRUH TZD, DIS a TIS
Číslo otázky : Otázka :
13. Základní datové struktury (pole, zásobník, binární strom atd.), datové struktury vhodné pro fyzickou implementaci relačních dat v SŘBD (hašovací tabulky, B-strom)..
Obsah : 1 Úvod 2 Základní datové struktury 2.1 lineární datové struktury 2.1.1 Pole 2.1.2 Zásobník 2.1.3 Fronta 2.1.4 Seznam 2.2 NElineární datové struktury 2.2.1 Binární stromy 2.2.2 AVL stromy 2.2.3 2-3-4 Stromy 2.2.4 Read-Black Stromy 2.2.5 Uložení řetězců 2.2.6 Trie 2.2.7 Ternární stromy 3 Struktury vhodné pro fyzickou implementaci relačních dat v SŘBD 3.1 Hašování 3.1.1 Přímo adresovatelné tabulky 3.1.2 Hašovací tabulky 3.2 B-strom
2. Základní datové struktury 2.1.1 Pole Datová struktura, která sdružuje daný počet prvků (čísel, textových řetězců, … ) o stejné velikosti. K jednotlivým prvkům pole se přistupuje pomocí jejich indexu (celého čísla, označujícího pořadí prvku). Proto říkáme že pole je strukturou s přímým nebo náhodným přístupem.Počet prvků pole může být učen pevně nebo se může měnit v době zpracování. V prvním případě nazýváme pole statickým a ve druhém dynamickým. Operace s polem: • přístup k prvku – probíhá v konstatním čase, pomocí indexu lze vypočítat přesnou adresu v paměti (viz pointerová aritmetika) • vyhledávání prvku – (lineární vyhledávání) probíhá v čase O(N); v nejhorším případě je nutné projít celé pole (sekvenční vyhledánání) • vyhledávání prvku v seřazeném poli – hledání metodou půlení intervalu indexů pole (binární hledání), složitost O(log N). (Vyhledávání s binárním půlením) Různé programovací jazyky se (mimo jiné) liší v tom, jakým indexem označují první prvek pole . • C, C++, C#, Java a další indexují od nuly (a index vynásobený velikostí prvku v bytech vyjadřuje posunutí příslušného prvku v paměti od počátku pole) • BASIC indexuje od jedničky, což odpovídá matematickému značení a přirozenému počítání • Visual Basic, Pascal a umožňují nastavit horní a dolní meze pole individuálně
vícerozměrná pole: V praktických úlohách, zejména v náročnějších výpočetních a grafických aplikacích, se uplatňují i vícerozměrná pole. Ta se indexují uspořádanou k-ticí celých čísel (souřadnic) - např. ''a[3, 2, 5]''. Obzvláště často se používají dvourozměrná pole (matice), přičemž počet rozměrů pole je v drtivé většině případů menší nebo roven 3.
2.1.2 Zásobník LIFO Pro zásobník je charakteristický způsob manipulace s daty - data uložena jako poslední budou čtena jako první. Proto se používá také výraz LIFO z anglického „Last In – First Out“. Zásobník lze přirovnat k zásobníku v pistoli. Ukazatel na aktuální prvek v zásobníku se nazývá vrchol zásobníku (stack pointer). Opkem je pak ndo zásobníku.Operace vložení prvku se nazývá Push a vyjmutí se nazývá Pop. Jako poslední se u zásobníku implemementuje doraz Empty, který identifikuje prázdnost zásobníku. Někdy se přidává dotaz Top, který vrací prvek z vrcholu zásobníku, aniz by ho vyjmul (nedestuktivní varianty Pop). Pokud provedeme opreaci Pop na prázdném zásobníku nastává chyba podtečení (underflow). Zásobník má teoreticky neomezenou kapacitu. Pokud ji omezíme a nelze přidat další prvek nastává chyba přetčení (overfolw). Všechny operace lze provést v konstantním čase, nzávisí tedy na velikosti zásobníku. Zásobník lze implementovat pomocí statických proměnných (v poli) nebo pomocí dynamických proměnných (dynamicky alokované záznamy a ukazatele na ně)
2.1.3 Fronta FIFO Front uplatňuje mechanizmus přístupu FIFO „First In – First Out“. Jako první j z frontyodebrán prvek, který do ní byl vložený jako první. Obdoba fronty jak ji známe z reálného života. Oprave vložení prvkuse nazývá Put, operace odebrání potom Get. Jako u zásobníku se definuje oprace Empty, inikující prázdnost fronty. Oprace ket nad prázdnou frontou vede kchybě podtečení. U velikostně omezené fronty může nastat hyba přetečení, překročíme.li při vkládání přidělený prostor. Pro implementaci fronty jsou potřeba 2 ukazatele. Jedna určuje začátek fronty hlavu (head) , ukazuje na prvek, který je na řadě pro odebrání. Druhým ukazatelem je ocas (tail), ukazuje na poslední prvek ve frontě.
2.1.4 Seznam Dynamická datová struktura, vzdáleně podobná poli (umožňuje uchovat velké množství hodnot ale jiným způsobem), obsahující jednu a více datových položek (struktur) stejného typu, které jsou navzájem lineárně provázany vzájemnýmí odkazy pomocí ukazatelů nebo referencí. Aby byl seznam lineární, nesmí existovat cykly ve vzájemných odkazech. Lineární seznamy mohou existovat jednosměrné a obousměrné. V jednosměrném seznamu odkazuje každá položka na položku následující a v obousměrném seznamu odkazuje položka na následující i předcházející položky. Pokud prvek x nemá předchůdce tento prvek tvoří hlahou seznamu. Pokud prvek x nemá následovníka pak tvoří ocas seznamu.Pokud vytvoříme cyklus tak, že konec seznamu navážeme na jeho počátek, jedná se o kruhový seznam. Seznam nazýváme setřízený jestliže prvky seznamu jsou setřízeny. V opačném případě je seznam nesetřízený. Seznamy tedy mohou být: • • • •
jednosměrný obousměrný cyklické acyklické
2.2 NElineární datové struktury 2.2.1 Binární stromy Binární strom je strom ve smyslu používaném v teorii grafů. Jedná se o orientovaný graf s jedním vrcholem (kořenem), z něhož existuje cesta do všech vrcholů grafu. Každý vrchol binárního stromu může mít maximálně dva orientované syny a s výjimkou kořene právě jednoho předka. Kořen předka nemá. Na binárních stromch lze implementovat oprace maximum, minimum. 1. pomocí dynamické struktury, kde jsou hrany reprezentovány ukazateli. Takto se reprezentuje například AVL-strom 2. pomocí pole, kde prvek s indexem i má následníky s indexem 2i a 2i+1 (za předpokladu, že pole je indexováno od 1). Takto je například reprezentovaná halda v algoritmu heapsort. Binární strom je nejčastěji používán jako binární vyhledávací strom a halda.
2.2.2 AVL stromy Je datová struktura pro uchovávání údajů a jejich vyhledávání. Pracuje v logaritmicky
omezeném čase. Jedná se o samovyvažující se binární vyhledávací strom. Vlastnosti vrcholů AVL stromu: • Vrchol má maximálně dva následníky (je to binární strom). • V levém podstromu vrcholu jsou pouze vrcholy s menší hodnotou klíče (je to binární vyhledávací strom). • V pravém podstromu vrcholu jsou pouze vrcholy s větší hodnotou klíče (je to vyhledávací strom). • Délka nejdelší větve levého a pravého podstromu se liší nejvýše o 1 (vyvážení AVL stromu). Hlavní vlastností AVL stromu je, že definice nedovoluje, aby strom zdegeneroval, tj. zajišťuje vyváženost stromu. Vyvažování: Operace potřebné pro vyvažování jsou realizovány cyklickými záměnami ukazatelů. Můžeme provádět jednoduché RR-rotace (pravá rotace), LL-rotace (levá rotace) nebo dvojité LRrotace (nejprve levá a potom pravá), RL-rotace (nejprve pravá a potom levá). Při rotaci je nutné aktualizovat koeficient vyváženosti každého rotovaného uzlu.
Ukázka RR-rotace stromu
Ukázka LL-rotace stromu
Ukázka RL-rotace stromu
Ukázka LR-rotace stromu
2.2.3 2-3-4 Stromy Uzly stromu mohou obsahovat více než jeden klíč. Přesněji řečeno vytvoříme 2-3-4 strom se třemi novými typy uzlů 3-uzel a 4-uzel, které mají tři resp. čtyři ukazatele ukazující na potomky. 3-uzel resp. 4-uzel obsahuje dva resp. tři klíče. První ukazatel v 3uzlu ukazuje na uzel s klíčí menšími než oba klíče aktuálního uzlu, druhý ukazuje na uzel s hodnotami klíčů mezi oběma klíčí aktuálního uzlu a třetí na uzel s klíčí vyššími. Obdobná situace nastává u 4-uzlu. (Uzly ve standardním vyhledávacím binárním stromu pak můžeme nazývat 2-uzly; jeden klíč, dva ukazatele).
Dělení 4-uzlu
2.2.4 Read-Black Stromy (Red-Black Stromy Binární Vyhledávací Stromy, u kterých jee časová ...) Red–Black strom je binární strom s jedním dvouhodnotovým příznakem v uzlu navíc. Tento příznak představuje barvu uzlu, která může být červená nebo černá. Red–Black strom zajišt’uje, že žádná cesta z kořene do libovolného listu stromu nebude dvakrát delší než kterákoli jiná, to znamená, že strom je přibližně vyvážený. Každý uzel se skládá z položek: key, color, left child, right child a parent. Jestliže potomek nebo rodič uzlu neexistují, příslušný ukazatel je nastaven na null/NULL. Je vhodné uvažovat ukazatele NULL jako listy binárního stromu.
Definice (Red–Black strom). Binární vyhledávací strom je Red–Black strom, jestliže splňuje následující kritéria: 1 Každý uzel je bud’ černý nebo červený. 2 Každý list (NULL) je černý. 3 Jestliže je daný uzel červený, pak jeho potomci jsou černí. 4 Každá cesta z libovolného uzlu do listu obsahuje stejný počet černých uzlů Počet černých uzlů na cestě z uzlu x do listu (mimo uzel x) nazýváme černou výškou uzlu x, píšeme bh(x). Dále definujeme černou výšku stromu jako černou výšku kořene stromu. Rozeznáváme dva druhy rotací: levou a pravou. Levá rotace x pracuje s ukazatelem z x do y. Uzel y se stane novým kořenem stromu, s uzlem x jako svým levým potomkem a levý potomek y se napojí jako pravý potomek x.
2.2.5 Uložení řetězců Pro uložení množiny řetězců si můžeme vybrat z několika datových struktur. Jednou
z možností je použití hashovacích tabulek. Jejich výhodou je rychlý přístup k datům, ale nevýhodou je ztráta informace o relativním pořadí. Jinou možností je uložení řetězců do binárního vyhledávacího stromu, jehož výhodou je malá prostorová složitost. Dále můžeme použít tzv. vyhledávací trie, jsou rychlé ale mají velkou prostorovou složitost. 2.2.6 Trie Vyhledávací trie ukládají řetězce znak po znaku. Každé vstupní slovo je zobrazeno pod uzlem, který jej reprezentuje. Ve stromě, který reprezentuje např. slova skládající se jen z malých písmen, má každý uzel 26 následovníků (anglická abeceda). Vyhledávání je velmi rychlé, v každém uzlu vlastně přistupujeme k prvku pole (jednomu z 26), testujeme na NULL/null a vybíráme větev. Trie bohužel mají nadměrnou prostorovou složitost. Uzel, ze kterého vychází 26 větví typicky vyžaduje 104 bytů, uzel s 256 větvemi spotřebuje 1kB.
2.2.7 Ternární stromy Kombinuje přednosti ds trie a binárních vyhledávacích stromů - časovou efektivitu a prostorovou efektivitu. Stejně jako trie postupují znak po znaku. Stejně jako binární stromy jsou prostorově efektivní, každý uzel má 3 potomky (oproti dvěma u binárních stromůu). Při vyhledávání se porovnává aktuální znak řetězce se znakem v uzlu. Pokud hledaný znak je menší než aktuální uzel, pokračujeme levým potomkem. Je-li větší pokračujeme pravým potomkem. Pokud jsou si znaky rovny, pokračujeme prostředním potomkem a vyhledáváme následující znak v řetězci.
3. Struktury vhodné pro fyzickou implementaci relačních dat v SŘBD 3.1 Hašování KRÁTKÝ Hashovacı tabulky nabízí nástroje jak vytvaářet velice efektivní tabulky, kde složitost vyhledávání je, za několika rozumných předpokladů , rovna (1). I když nejhorší případ je stále (n). Přímo adresovatelné tabulky a hashovací tabulky jsou rozšířením standardních polí. Přímo adresovatelné tabulky používají přímo klíče jako indexy v poli, hashovací tabulky transformují prostor klíčů o velmi velké mohutnosti pomocıí hashovací funkce do relativně malého prostoru indexů pole.
3.1.1 Přímo adresovatelné tabulky Přímé adresování je jednoduchá technika, kteraá dobře funguje, pokud univerzum klíčů U má malou mohutnost. Pro reprezentaci takové množiny použijeme pole nebo přímo adresovatelnou tabulku.
3.1.2 Hašovací tabulky KRÁTKÝ: Hlavní problém s přímým adresováním je zřejmý: jestliže univerzum U je velké , udržování tabulky T velikosti |U| je nepraktické , většině počítačů ne-li přímo nemožné. V přímo adresovatelné tabulce je prvek s klíčem k uložen ve slotu k. V hashovací tabulce je uložen ve slotu h(k), kde h je hashovací funkce. Hashovací funkce h zobrazuje univerzum klíčů U na sloty hashovací tabulky T[0 . . .m − 1]: h : U -> {0, 1, . . . ,m − 1}
Říkáme, že prvek s klíčem k je hashován do slotu h(k), říkáme také , že h(k) je hashovací hodnota klíče k. Hlavním účelem hashovací funkce je transformace klíčů z univerza U do jednotlivých slotů . Tím se také zmenšují nároky na pamě t’. Místo původních |U| klíčů stačí udržovat jen m hodnot. Je jasné , že celá tato konstrukce má jednu vadu. Dva klíče se mohou hashovací funkcí zobrazit na tentýž slot – dojde ke kolizi. Naštěstí existují učinné techniky jak kolize prvků řešit. Řešení konfliktů: 1. Technika separátního řetězení řeší kolize velice jednoduše. V hashovací tabulce je v každém slotu pointer na seznama prvky se stejnou hodnotou hashovací funkce se vkládají do příslušného seznamu 2. Pří použití otevřeného adresování jsou všechny prvky uloženy přímo v hashovací tabulce. Každý slot tabulky obsahuje bud’ nějaký prvek nebo je prázdný. Při hledání prvku v tabulce systematicky prohledáváme sloty tabulky dokud nenajdeme hledaný prvek nebo najdeme prázdný slot. Na rozdíl od separátního řetězení nejsou ke slotům připojeny žádné seznamy, tabulka je jen průběžně plněna. Hlavní výhodou otevřeného adresování je úspora místa, poněvadž místo pointerů tato metoda vypočítává posloupnost slotů , které je nutno prozkoumat. Při vkládání prvku do hashovací tabulky provádíme takzvané pokusy dokud nenajdeme hledaný prvek nebo prázdný slot. (Lineární pokusy, Kvadratické pokusy, Dvojité hashování) WIKI: Je datová struktura, která asociuje hashovací klíče s odpovídajícími hodnotami. Hodnota klíče je spočtena z obsahu položky podle takového pravidla (viz hashovací funkce), aby klíč byl co nejjednoznačněji určen, tj. aby pravděpodobnost přiřazení stejného klíče dvěma a více rozdílným položkám byla co nejnižší a aby rozptyl hodnot klíčů pro dvě obsahově blízké položky byl co nejvyšší.
3.2 B-Stromy Je specifický tím, že má řád n a limity na maximální (n), i minimální (n/2) počet potomků vrcholu. B-strom je díky této vlastnosti vyvážený, operace přidání, vyjmutí i vyhledávání tedy probíhají v logaritmickém čase. Tato struktura je často používána v aplikacích, kdy není celá struktura uložena v paměti RAM, ale v nějaké sekundární paměti, jako je pevný disk (například databáze). Protože přístup do tohoto typu paměti je náročný na čas (hlavně vyhledání náhodné položky), snažíme se minimalizovat počet přístupů do této paměti. Příklad: Máme-li B-strom hloubky 2 a počet potomků každého uzlu je 1001, můžeme do něj uložit milion klíčů a ke každé položce se dostaneme maximálně po dvou diskových operacích. KRÁTKÝ B-strom řádu n je (2n+1)-ární strom, který splňuje následující kritéri 1. Každá stránka obsahuje nejvýše 2n položek (klíčů ). 2. Každá stránka, s vyjímkou kořenové obsahuje alespoň n položek. 3. Každá stránka je bud’ listovou tj. nemá žádné následovníky nebo má m+1
násleodvníků , kde m je počet klíčů ve stránce. 4. Všechny listové stránky jsou na stejné úrovni.