You are on page 1of 5

Reprezentace grafu, stromu v programu

Matice sousednosti:
 Matice sousednosti je dvojrozměrné pole, ve kterém položka na daném páru indexů značí,
vede-li mezi vrcholy s těmito indexy hrana. Obě dvě dimenze matice sousednosti mají velikost
stejnou jako počet vrcholů v grafu. Matice sousednosti zabírá V2 místa, kdy V je číslo vrcholů
grafu. Zjištění sousednosti dvou vrcholů je O(1) (zaindexování do pole), ale zjištění všech
sousedních vrcholů nějakého vrcholu je O(V), protože musíme projet celou řadu. Pozn.:
náročnosti a místo je spíše pro zajímavost.
 U neorientovaného grafu bude matice osově souměrná podle jedné úhlopříčky (hrana vede
z 1 do 3 i z 3 do 1, jelikož je obousměrná), kdežto u orientovaného zpravidla není.
 U ohodnoceného grafu můžeme použít místo pole booleanů integery a používat pomocnou
hodnotu (záleží na grafu – může být 0, pokud je ohodnocený kladně, nebo třeba nějaká
záporná hodnota, pokud je nezáporně ohodnocený, nebo třeba max int value).

Seznam hran:
 Seznam hran je pole, které má tolik položek, kolik je hran v grafu. Každá položka je buď další
pole, nebo objekt, ve kterém je uložena informace o jedné hraně. Seznam hran zabírá E místa,
kdy E je počet hran v grafu. Náročnost zjištění, jestli je mezi dvěma vrcholy hrana, a náročnost
zjištění všech vrcholů, které sousedí danému vrcholu, je O(E).
 U neohodnocených grafů sestává informace o hraně ze dvou položek – počáteční vrchol hrany
a koncový vrchol hrany, přičemž u neorientovaného grafu nezáleží na jejich pořadí, u
orientovaného ano.
 U ohodnocených grafů mají pole pro jednotlivé hrany ještě navíc své ohodnocení, tedy tři
položky.

Seznam sousednosti:
 Seznam sousednosti je pole o velikosti V (V je počet vrcholů), přičemž v každé položce tohoto
pole je uložen seznam vrcholů, které sousedí vrcholu s daným indexem. Seznam vrcholů
může být reprezentovaný mnoha způsoby – spojový seznam, nafukovací pole nebo normální
pole (záleží, jestli chceme přidávat prvky). Zjištění, jestli dva vrcholy sousedí zabre, a zjištění
všech sousedů daného vrcholu je náročné O(d), kdy d je počet sousedních vrcholů (worst
case je to O(V-1), ale v praxi většinou mnohem méně). Seznam sousednosti zabírá 2E místa.
 U neorientovaných grafů nesmíme zapomenout přidat sousední vrchol b k a i a k b.
 Pokud je graf ohodnocený je v seznamu sousedních vrcholů uložena ještě n avíc hodnota
hrany (položka v seznamu sousedních vrcholů je buď pole o dvou položkách, nebo objekt).
Strom:
 Pokud je binární a kompletní (každá vrstva je zcela zaplněna zleva, než se přidávají prvky do
další), můžeme použít pole – viz halda (začínáme od 1, potomci vrcholu mají index otce*2 a
index otce*2+1)
 V ostatních případech se používá systém uzlů a odkazů – každý uzel má v sobě uloženou
informaci (třeba int, String apod.), odkaz na svého rodiče a odkazy na své potomky. Poznámka:
takto se dá vyjádřit jakákoliv graf. Pravidla hierarchie vrcholů a přidávání vrcholů do stromu
záleží na typu daného stromu – nemá smysl chodit do detailu.

Reprezentace výrazu binárním stromem


 Binární strom (každý uzel má nejvýše dva potomky), ve kterém každý list je číslo a každý
vnitřní uzel je znaménko
 Neuvěřitelně lehké vyčíslovaní takto zapsaného výrazu rekurzivně:
1. Pokud je informace v uzlu číslo, vrať toto číslo
2. Pokud je informace v uzlu znaménko, zavolej stejnou funkci na oba syny a
s vrácenými hodnotami proveď patřičnou operaci, výsledek této operace vrať
 Horší je takový strom postavit – nejlépe se to dělá asi z postfixové notace pomocí zásobníku
(jde to asi i z prefixu, ale horší)
 Příklad pro výraz 3+((5+9)*2):

Aritmetické notace
Infix:
 Známenko je mezi čísly, s nimiž provádí aritmetickou operaci
 Běžně používaná syntaxe
 Syntaxe není jednoznačná, je potřeba závorek k upřesnění pořadí operací, když má být
provedeno sčítání nebo odčítání před násobením nebo dělením
 Z hlediska vyčíslování na píču – potřebujeme závorky, které vše komplikují

Postfix:
 Známenko následuje po číslech, s nimiž provádí aritmetickou operaci
 Syntaxe je jednoznačná, není potřeba závorek
 Z hlediska vyčíslování pomocí kódu nejlepší – čísla ukládáme postupně do zásobníku, a když
přijde znaménko můžeme rovnou provést operaci a výsledek rovnou uložit opět do zásobníku

Prefix:
 Známenko předchází čísla, s nimiž provádí aritmetickou operaci
 Syntaxe je jednoznačná, není potřeba závorek
 Z hlediska vyčíslovaní pomocí kódu provádíme jako postfix – pointer dáme na konec výrazu a
opět používáme zásobník na čísla

Převod z infixu do postfixu:


1. Připravíme si zásobník na znaménka a závorky
2. Projíždíme výraz po znacích
3. Pokud je znak číslo, rovnou ho přidáme do výrazu v postfixu
4. Pokud je znak znaménko, podíváme se do zásobníku na poslední znaménko
a. má-li poslední znaménko vyšší nebo stejnou prioritu jako aktuální znaménko,
odebereme poslední znaménko ze zásobníku a přidáme do výrazu v postfixu a proces
opakujeme, dokud nenarazíme na znaménko s nižší prioritou, závorku nebo dokud
zásobník není prázdný; po přidání všech znamének nevyhovujících podmínce do
postfixu přidáme aktuální znaménko do zásobníku
b. má-li poslední znaménko nižší prioritu, pouze přidáme aktuální znaménko do
zásobníku
5. Pokud je znak otevírací závorka, přidáme ji do zásobníku, pokud je znak uzavírací závorka,
odebereme všechna znaménka ze zásobníku a přidáme je do výrazu v postfixu, dokud
nenarazíme na otevírací závorku, kterou také odebereme ze zásobníku, ale do výrazu
nepřidáme

Priority znamének: + a - mají prioritu 1; * a / mají prioritu 2; a ^ má prioritu 3

Příklad převodu na yt: https://www.youtube.com/watch?v=vXPL6UavUeA

Vyčíslování výrazu v postfixu:


1. Připravíme si zásobník na čísla
2. Projíždíme výraz po znacích
3. Pokud je znak číslo, přidáme ho do zásobníku
4. Pokud je znak znaménko, vyndáme ze zásobníku poslední dvě čísla, provedeme s nimi
patřičnou operaci (u dělení, odčítání a mocnění záleží na pořadí čísel – první je předposlední,
poté poslední př.: předposlední-poslední; předposlední/poslední) a výsledek opět přidáme do
zásobníku

Příklad vyčíslení na yt: https://www.youtube.com/watch?v=QCnANUfgC-w


Vyhodnocení aritmetického výrazu metodou rozděl a panuj
Metoda rozděl a panuj spočívá v rozdělení velkého problému na menší problémy, které umíme
snadno vyřešit, a využití řešení těchto malých problémů k vyřešení velkého problému. Mějme funkci
Vyčísli, jejímž parametrem je řetězec reprezentující výraz. Algoritmus užitý ve funkci Vyčísli je
následující:

1. Zkontroluje délku řetězce - jestli je 1, znamená to, že je to číslo. Vrátí tedy jeho číselnou
hodnotu
2. Pokud je více než jedna, projde řetězec po znacích a najde znaménko s nejnižší prioritou
(priorita je určená typem znaménka a počtem závorek, ve kterých se nachází)
3. Po nalezení znaménka s nejnižší prioritou zavolá rekurzivně funkci Vyčísli na výraz vpravo od
tohoto znaménka a na výraz vlevo od tohoto znaménka a s výsledky, které ji rekurzivní volání
vrátí, provede patřičnou operaci a výsledek vrátí

Po skončení rekurze máme výsledek výrazu.

You might also like