190 likes | 430 Views
Stromy. Opakování. Co je to graf? Co je to sled, tah, cesta? Co je to eulerovský a hamiltonovský graf? Co je to (slabě / silně) souvislý graf? Co je to izomorfismus grafů? Co je to matice sousednosti? Co je to matice incidence? Jak jinak lze implementovat graf?. Definice pojmů.
E N D
Opakování • Co je to graf? • Co je to sled, tah, cesta? • Co je to eulerovský a hamiltonovský graf? • Co je to (slabě / silně) souvislý graf? • Co je to izomorfismus grafů? • Co je to matice sousednosti? • Co je to matice incidence? • Jak jinak lze implementovat graf?
Definice pojmů • Graf bez kružnic (acyklický graf) se nazývá les • Souvislý les se nazývá strom • Les je tedy takový graf, jehož každou komponentou je strom • Stromy mohou být • neorientované • orientované (kořenové)
Vlastnosti stromů • Je dán strom G = (U, H, f). Pak |H| = |U| – 1 • důkaz indukcí přes počet uzlů stromu • Mezi každými dvěma uzly stromu vede jediná cesta • Přidáním jedné nové hrany do stromu vznikne kružnice (právě jedna) • Každý uzel stromu je artikulace, každá hrana stromu je most • Strom je minimální souvislý graf na daných vrcholech
Neorientované stromy • Uzel se stupněm 1 nazveme list. • Každý strom obsahuje alespoň jeden list • v grafu, kde stupeň každého uzlu ≥ 2 musí existovat kružnice • Graf vzniknuvší ze stromu odstraněním libovolného listu a s ním incidentní hrany, je opět strom.
Kořenový strom I. • Orientovaný strom je graf, jehož symetrizace je strom. • Jestliže vybereme jeden uzel, který nazveme kořen, a všechny hrany jsou orientovány směrem od kořene, získáváme kořenový strom. • Pro daný uzel pak hovoříme o • předchůdcích (rodičích) • následnících (potomcích) • sousedech (sourozencích) • Uzel bez potomků se nazývá list • vstupní stupeň = 1, výstupní stupeň = 0
Kořenový strom II. • Vzdálenost uzlu od kořene se nazývá výška uzlu. • Výška stromu je výška uzlu (listu) s největší výškou. • Liší-li vzdálenost (délka cesty) mezi kořenem a všemi listy nejvýše o 1, mluvíme o vyváženém stromu
Aplikace stromů • Uzlově ohodnocený strom • Binární vyhledávací strom • složitost vyhledávání je log(n) a ne n • je-li strom vyvážený • Řazení algoritmem heap-sort • časová složitost n*log(n) • Kódování • Morse, Huffmann, …
Binární vyhledávací strom • Binární vyhledávací strom (BST) je uspořádaný binární uzlově ohodnocený strom, v němž pro každý uzel platí • hodnoty v levém podstromu jsou menší, než hodnota v daném uzlu • hodnoty v pravém podstromu jsou větší, než hodnota v daném uzlu • někdy připouštíme i rovnost, ale jen v 1 směru • Algoritmy: • vyhledání uzlu • přidání uzlu • odebrání uzlu
BVS: Vyhledávání Sekvenčně: v := T (kořen) while (v ≠ NULL) and (v.key ≠ k) do if k<v.key then v := v.left; else v := v.right; return v; Rekurzivní BSTsearch(v,k): if v = NULL then return NULL else if v.key = k then return v else if k<v.key then return BSTsearch(v.left, k) else return BSTsearch(v.right, k) • Vstup: strom T, klíč k • Výstup: ukazatel na uzel s klíčem k nebo NULL • Otázka: Jak implementovat vkládání a rušení uzlu?
AVL stromy • Pojmenován po autorech • Adelson-Velskii a Landis • Samovyvažující binární vyhledávací strom • Pro každý uzel platí • v levém podstromu jsou menší klíče • v pravém podstromu jsou větší klíče • výška levého a pravého podstromu se liší nejvýše o 1 • U každého uzlu koeficient vyváženosti • rozdíl výšek levého a pravého podstromu
Vkládání uzlu do AVL stromu • Vložíme uzel jako v BVS • Aktualizujeme koeficienty vyváženosti • Provedeme vyvážení pomocí cyklických záměn ukazatelů • levá nebo pravá rotace: novým kořenem se stává kořen vyššího podstromu • maximálně dvě (protisměrné) rotace na jedno vložení
Vyvažování AVL stromu: levá rotace • Pravý podstrom o 2 vyšší než levý • v pravém podstromu je vyšší pravý podstrom • Analogicky pravá rotace zdroj: wikipedia
Vyvažování AVL stromu: dvojitá rotace • Pravý podstrm o 2 vyšší než levý • v pravém podstromu vyšší levý podstrom • Analogicky opačné rotace
Rušení uzlu z AVL stromu • Je-li rušený uzel list, odebereme jej • Není-li, je třeba jej nahradit nejlevějším uzlem pravého podstromu nebo nejpravějším uzlem levého podstromu • Ten může mít maximálně 1 podstrom; jeho kořen jde na místo zrušeného uzlu • Aktualizujeme koeficienty vyváženosti až ke kořeni • V případě potřeby provedeme vyvážení
Halda (heap) • Statická reprezentace prioritního stromu • zleva úplný vyvážený binární strom • každý uzel nese vyšší hodnotu, než všichni jeho potomci • maximální hodnota je tedy v kořeni • Pole, v němž jsou uzly určeny indexy • kořen má index 0 • levý potomek uzlu s indexem n má index 2n+1 • pravý potomek uzlu s indexem n má index 2n+2 • rodič uzlu s indexem n má index [(n-1)/2] • Halda šetří místo, protože není potřeba ukládat ukazatele
Vkládání do haldy • Vložíme nový uzel na nejbližší volnou pozici tak, aby strom zůstal zleva úplný • Dokud má vkládaný uzel větší prioritu, než jeho rodič, vyměníme je • “probubláváme” s uzlem směrem nahoru na správné místo • Maximální počet výměn je h = log2n
Vybírání z haldy • Vždy vybíráme kořen • protože má nejvyšší prioritu • Na jeho místo vložíme nejpravější list (L) maximální výšky • kvůli zachování levé úplnosti stromu • Dokud má L nižší prioritu než některý z jeho potomků, vyměníme jej s potomkem vyšší priority • “probubláváme” s uzlem směrem dolů • Maximální počet výměn je h = log2n
Heap sort • Řazení haldou • Vybudování haldy vložením všech prvků • n*log(n) • Postupné odebírání kořene a rekonstrukce haldy • n*log(n)