Dynamické dátové štruktúry a algoritmy

Ponorte sa do sveta dynamických dátových štruktúr a algoritmov. Naučte sa ich charakteristiku, použitie a zložitosť. Kompletný sprievodca pre študentov informatiky!

Podcast

Dátové štruktúry: Od triedenia po hašovanie0:00 / 13:37
0:001:00 zostáva

Dynamické dátové štruktúry a algoritmy sú základným kameňom informatiky a programovania. Umožňujú efektívne spracovávať a organizovať dáta, ktorých objem alebo štruktúra sa mení počas behu programu. Tento komplexný sprievodca pre študentov vás prevedie ich kľúčovými konceptmi a praktickým využitím.

Čo sú Dynamické Dátové Štruktúry a Algoritmy?

Dynamické dátové štruktúry sú také dátové štruktúry, ktorých veľkosť sa môže počas behu programu meniť. Prvky môžeme podľa potreby pridávať, odoberať alebo prepájať. Používajú sa najmä vtedy, keď dopredu nevieme presný počet prvkov. Správny výber dynamickej dátovej štruktúry a algoritmu je kľúčový pre efektívnosť programu.

Efektívnosť Operácií a Asymptotická Zložitosť

Pri výbere dátovej štruktúry a algoritmu sledujeme aj efektívnosť operácií. Čas behu algoritmu označujeme T(n), kde n je veľkosť vstupu. Zaujíma nás, ako sa čas behu mení pri zväčšovaní vstupu, čo opisuje asymptotická zložitosť. Najčastejšie používame notáciu O, ktorá vyjadruje horný odhad rastu času.

Typické zložitosti zahŕňajú:

  • O(1) – konštantná (najrýchlejšia)
  • O(log n) – logaritmická
  • O(n) – lineárna
  • O(n log n) – typická efektívna zložitosť triediacich algoritmov
  • O(n²) – kvadratická (neefektívna pri veľkých dátach)

Rozlišujeme tiež najlepší prípad (best-case), priemerný prípad (average-case) a najhorší prípad (worst-case).

Časová a Pamäťová Zložitosť Algoritmov

Časová zložitosť vyjadruje počet operácií v závislosti od veľkosti vstupu n. Udáva, ako dlho bude algoritmus trvať. Pamäťová zložitosť udáva množstvo dodatočnej pamäte, ktoré algoritmus potrebuje. In-place algoritmy potrebujú len O(1) alebo O(log n) pamäte, zatiaľ čo externé algoritmy môžu vyžadovať O(n).

Spájaný Zoznam: Flexibilná Štruktúra Dát

Spájaný zoznam je kľúčovou dynamickou dátovou štruktúrou, ktorá umožňuje jednoduché pridávanie a odoberanie prvkov bez nutnosti presúvania iných dát v pamäti. Na rozdiel od polí, prvky spájaného zoznamu nemusia byť uložené súvisle v pamäti. Každý prvok, nazývaný vrchol, obsahuje dáta a odkaz na nasledujúci prvok.

Jednosmerný Spájaný Zoznam

V jednosmernom spájanom zozname každý vrchol obsahuje odkaz (referenciu) na nasledujúci prvok. Tento odkaz sa môže označovať aj ako adresa alebo link. Spájaný zoznam je vždy prístupný pomocou premennej, ktorá odkazuje na prvý vrchol.

Schéma jednosmerného zoznamu:

[ data | next ] → [ data | next ] → [ data | next ] → None

Posledný vrchol nemá nasledovníka, preto obsahuje špeciálnu hodnotu (napríklad None v Pythone).

Vlastnosti:

  • Prvky nemusia byť uložené vedľa seba v pamäti.
  • Vieme ľahko pridávať a odoberať prvky.
  • Prístup k prvkom je sekvenčný (musíme prechádzať postupne).

Dvojito Spájaný Zoznam

Pri dvojito spájanom zozname obsahuje každý vrchol dva odkazy: jeden na predchádzajúci prvok (prev) a druhý na nasledujúci prvok (next). To umožňuje prechádzať zoznamom v oboch smeroch.

Schéma dvojito spájaného zoznamu:

None ← [prev | data | next] ⇄ [prev | data | next] ⇄ [prev | data | next] → None

Vlastnosti:

  • Zoznam môžeme prechádzať v oboch smeroch.
  • Jednoduchšie je vymazávanie alebo vkladanie prvkov v porovnaní s jednosmerným zoznamom.
  • Potrebuje viac pamäte, pretože každý vrchol má dva odkazy.

Cyklický Spájaný Zoznam

Cyklický zoznam nemá koniec. Posledný prvok neukazuje na None, ale ukazuje späť na prvý prvok zoznamu, čím vzniká uzavretý kruh. Môže byť jednosmerný alebo dvojsmerný.

Schéma jednosmerného cyklického zoznamu:

[ data | next ] → [ data | next ] → [ data | next ] ↑_____________________________________|

Vlastnosti:

  • Zoznam sa dá prechádzať dookola stále dokola.
  • Často sa používa pri plánovaní procesov (napríklad round-robin), simuláciách alebo hrách.

Základné operácie so spájaným zoznamom zahŕňajú vytvorenie prázdneho zoznamu, pridanie prvku, odstránenie prvku, vyhľadanie prvku a prechod zoznamom. Tieto operácie sa zvyčajne implementujú ako metódy triedy.

Reprezentácia Množín s Rôznymi Dátovými Štruktúrami

Množina je abstraktný dátový typ, ktorý obsahuje neusporiadané prvky bez opakovania. V informatike sa množiny používajú napríklad pri práci s databázami alebo grafmi.

Základné operácie nad množinou sú:

  • vloženie prvku
  • odstránenie prvku
  • zistenie príslušnosti prvku
  • zjednotenie množín
  • prienik množín
  • rozdiel množín

Množinu možno implementovať rôznymi dátovými štruktúrami, ako je bitový vektor, pole, spájaný zoznam alebo strom.

Bitový Vektor pre Množiny

Bitový vektor je pole bitov, kde každý bit reprezentuje jeden prvok z univerzálnej množiny. Hodnota 1 znamená, že prvok je v množine, zatiaľ čo 0 znamená, že prvok v množine nie je. Napríklad, pre univerzálnu množinu {0,1,2,3,4} a bitový vektor [1,0,1,0,1] je reprezentovaná množina {0,2,4}.

Reprezentácia Množiny Pomocou Poľa

Množinu možno uložiť aj ako pole prvkov, napríklad [5, 8, 12, 20].

Operácie a Zložitosť:

  • Vloženie prvku: Pridanie do poľa, ak už prvok neexistuje. (Zložitosť: O(n) kvôli kontrole duplicity)
  • Vyhľadanie prvku: Lineárne prehľadanie poľa (Zložitosť: O(n))
  • Odstránenie prvku: Nájdenie prvku a jeho vymazanie (Zložitosť: O(n))

Výhody: Jednoduchá implementácia. Nevýhody: Pomalé vyhľadávanie a odstránenie.

Reprezentácia Množiny Pomocou Spájaného Zoznamu

Pri tejto reprezentácii je každý prvok samostatný uzol obsahujúci hodnotu a odkaz na ďalší prvok. Schéma: [3 | • ] → [7 | • ] → [10 | • ] → None.

Operácie a Zložitosť:

  • Vloženie prvku: O(1) na začiatok, ale pre kontrolu duplicity v množine O(n).
  • Vyhľadanie prvku: O(n).
  • Odstránenie prvku: O(n).

Výhody: Dynamická veľkosť, jednoduché vkladanie. Nevýhody: Pomalé vyhľadávanie.

Stromová Reprezentácia Množiny

Množiny sa často implementujú pomocou binárnych vyhľadávacích stromov (BST), ktoré umožňujú efektívnejšie operácie. V BST platí, že všetky prvky v ľavom podstrome sú menšie ako koreň a všetky prvky v pravom podstrome sú väčšie ako koreň.

Stromy: Hierarchické Dátové Štruktúry

Strom je hierarchická dátová štruktúra a špeciálny typ grafu. Je to súvislý acyklický graf, čo znamená, že medzi vrcholmi neexistujú žiadne cykly. Skladá sa z vrcholov (uzlov) a hrán (spojení).

Každý strom má jeden špeciálny vrchol nazývaný koreň (root), z ktorého štruktúra začína.

Základné Pojmy v Stromoch

  • Koreň (root): Najvyšší vrchol stromu.
  • Rodič (parent): Vrchol, ktorý má pod sebou ďalšie vrcholy.
  • Potomok (child): Vrchol, ktorý je priamo pod rodičom.
  • Podstrom: Strom, ktorý vznikne zvolením jedného vrcholu a všetkých jeho potomkov.
  • Hĺbka vrcholu: Počet hrán od koreňa k danému vrcholu.
  • Výška stromu: Najväčšia hĺbka vrcholu v strome.

Binárny Strom

Najčastejšie používaným typom je binárny strom, kde každý vrchol môže mať najviac dvoch potomkov: ľavého a pravého.

Schéma binárneho stromu:

 A
 / \
B C

Prechádzanie Stromu (Tree Traversal)

Pri práci so stromami sa často používa prechádzanie stromu. Medzi najznámejšie metódy patria:

  • Preorder: Koreň → ľavý podstrom → pravý podstrom
  • Inorder: Ľavý podstrom → koreň → pravý podstrom
  • Postorder: Ľavý podstrom → pravý podstrom → koreň

Použitie Stromov

Stromy sa používajú v mnohých oblastiach:

  • organizovanie dát v databázach
  • vyhľadávacie algoritmy
  • reprezentácia súborových systémov
  • implementácia výrazov v programovaní

Huffmanov Kód a Huffmanov Strom

Huffmanov kód sa používa na efektívne kódovanie znakov s cieľom znížiť veľkosť uložených dát. Častejšie sa vyskytujúce znaky dostanú kratší kód, menej časté dlhší. Ide o prefixový kód, čo zabezpečuje správne dekódovanie.

Na vytvorenie kódu sa používa Huffmanov strom.

  • Každý znak je na začiatku samostatný vrchol s priradenou frekvenciou výskytu.
  • Vnútorné vrcholy predstavujú súčet frekvencií svojich potomkov.
  • Pri prechádzaní stromu: ľavá hrana = 0, pravá hrana = 1. Kód znaku vznikne zapísaním 0 a 1 na ceste od koreňa k listu.

Postup vytvorenia Huffmanovho stromu:

  1. Zistíme frekvencie všetkých znakov.
  2. Každý znak vytvorí samostatný vrchol stromu.
  3. Vyberieme dva vrcholy s najmenšou frekvenciou a spojíme ich do nového vrcholu, ktorého frekvencia je súčet frekvencií.
  4. Tento proces opakujeme, kým nevznikne jeden strom.

Vyvážené a Nevyvážené Stromy

Binárny vyhľadávací strom (BST), ako už bolo spomenuté, udržiava usporiadanie: ľavé prvky sú menšie, pravé väčšie. Ak sa prvky vkladajú v zoradenom poradí (napr. 1,2,3,4,5), strom sa stane nevyváženým a správa sa ako spájaný zoznam. Operácie potom môžu mať zložitosť O(n).

Vyvážené stromy (napr. AVL strom) udržujú optimálnu štruktúru, vďaka čomu sú operácie efektívne s časovou zložitosťou približne O(log n). To je obzvlášť dôležité pre reprezentáciu usporiadanej množiny prvkov.

Operácie s BST:

  • INSERT(x) – vloženie prvku: Nový prvok vkladáme na také miesto, aby zostala zachovaná vlastnosť BST.
  • DELETE(x) – odstránenie prvku:
  • Ak je list, jednoducho ho odstránime.
  • Ak má jedného potomka, nahradíme ho potomkom.
  • Ak má dvoch potomkov, nahradíme ho najmenším prvkom z pravého podstromu alebo najväčším z ľavého podstromu.

Grafy: Reprezentácia Vzťahov Medzi Objektami

Graf je dátová štruktúra, ktorá slúži na reprezentáciu vzťahov medzi dvojicami objektov. Matematicky je definovaný ako dvojica G=(V,E), kde V je množina vrcholov (objektov) a E je množina hrán (vzťahov), ktoré spájajú vrcholy. Príkladom sú mestá ako vrcholy a cesty medzi nimi ako hrany.

Typy Grafov

  • Neorientovaný graf: Hrany nemajú smer (A—B). Spojenie existuje v oboch smeroch. Používa sa napríklad pri cestných sieťach alebo mapách.
  • Orientovaný graf (digraf): Hrany majú smer (A → B). Spojenie existuje z A do B, ale nemusí existovať z B do A. Využíva sa pri závislostiach úloh alebo sociálnych sieťach.

Základné Pojmy a Reprezentácia Grafov

Jedným zo spôsobov reprezentácie grafu je zoznam susedov. Každý vrchol obsahuje zoznam vrcholov, s ktorými je spojený (napr. A → B, C). Výhodou je menšia pamäťová náročnosť, nevýhodou pomalšie zisťovanie konkrétnej hrany.

Prehľadávanie Grafu: DFS a BFS

Na prehľadávanie grafov sa často používajú dva algoritmy:

  • DFS (Depth First Search) – prehľadávanie do hĺbky: Najprv spracuje vrchol a potom postupne pokračuje v prehľadávaní všetkých svojich susedov rekurzívnym algoritmom.
  • BFS (Breadth First Search) – prehľadávanie do šírky: Algoritmus najprv prejde všetky vrcholy vzdialené 1 od aktuálneho, potom všetky vzdialené 2, atď.

Použitie Grafov

Grafy sa používajú napríklad pri:

  • modelovaní dopravných sietí
  • sociálnych sieťach
  • počítačových sieťach
  • plánovaní úloh
  • vyhľadávaní najkratšej cesty

Kartičky

1 / 42

Čo sú dynamické dátové štruktúry a kedy sa používajú?

Dátové štruktúry, ktorých veľkosť sa môže počas behu programu meniť; umožňujú pridávať, odoberať alebo prepájať prvky a používajú sa, keď nepoznáme do

Ťukni na otočenie · Potiahni na navigáciu

Algoritmy Triedenia: Merge Sort a Quick Sort

Triediace algoritmy slúžia na usporiadanie prvkov podľa určitého kľúča (napríklad vzostupne). Pri ich hodnotení sledujeme najmä časovú a pamäťovú zložitosť, stabilitu (zachovanie poradia rovnakých prvkov) a praktickú použiteľnosť.

Dolná hranica pre porovnávacie triedenie je Ω(n log n), čo znamená, že žiadny porovnávací algoritmus nemôže byť asymptoticky rýchlejší.

Merge Sort

Merge Sort patrí medzi algoritmy typu „divide and conquer“ (rozdeľ a panuj).

Postup:

  1. Rozdelí pole na dve polovice.
  2. Rekurzívne ich utriedi.
  3. Spojí (merge) zoradené časti.

Rekurentný vzťah je T(n) = 2T(n/2) + O(n), kde riešením je T(n)=O(n log n).

Zložitosť:

  • Best-case: O(n log n)
  • Average-case: O(n log n)
  • Worst-case: O(n log n)

Vlastnosti:

  • Stabilný algoritmus.
  • Vyžaduje dodatočnú pamäť O(n).
  • Vhodný pre veľké dáta a externé triedenie.

Quick Sort

Quick Sort tiež patrí medzi „divide and conquer“ algoritmy.

Postup:

  1. Vyberie sa pivot.
  2. Rozdelí prvky na menšie a väčšie ako pivot.
  3. Rekurzívne sa triedia vzniknuté časti.

Zložitosť:

  • Best-case: O(n log n)
  • Average-case: O(n log n)
  • Worst-case: O(n²)

Vlastnosti:

  • Nestabilný algoritmus.
  • Pamäť: O(log n) (rekurzia).
  • Veľmi rýchly v praxi (dobrá cache lokalita).

Porovnanie Triediacich Algoritmov (Merge Sort vs. Quick Sort)

VlastnosťMerge SortQuick Sort
Čas (avg)O(n log n)O(n log n)
Čas (worst)O(n log n)O(n²)
PamäťO(n)O(log n)
StabilitaÁnoNie
Praktické použitieExterné triedenieInterné triedenie

Odhady Zložitosti Iteratívnych a Rekurzívnych Algoritmov

  • Iteratívne algoritmy: Jeden cyklus → O(n), dva vnorené cykly → O(n²).
  • Rekurzívne algoritmy: Používame rekurentné vzťahy alebo Master theorem. Typický prípad rozdelenia na polovice vedie k log n úrovniam a práci O(n) na úrovni, čo dáva výsledok O(n log n).

Vyhľadávanie Informácií v Tabuľkách

Efektívne vyhľadávanie je kľúčové pre prácu s dátami. Existujú rôzne metódy v závislosti od usporiadania dát.

Sekvenčné (Lineárne) Vyhľadávanie

Je to najjednoduchší spôsob vyhľadávania.

Postup:

  1. Začneme od prvého prvku tabuľky.
  2. Postupne porovnávame každý prvok s hľadanou hodnotou.
  3. Ak sa hodnota nájde, vyhľadávanie sa končí.
  4. Ak prejdeme celú tabuľku, prvok sa v nej nenachádza.

Výhody: Jednoduchá implementácia, funguje aj na neusporiadaných dátach. Nevýhody: Pomalé pri veľkých množstvách dát.

Časová zložitosť:

  • Best-case: O(1)
  • Average-case: O(n)
  • Worst-case: O(n)

Binárne Vyhľadávanie

Binárne vyhľadávanie je efektívnejší algoritmus, ktorý sa používa iba na usporiadaných dátach.

Postup:

  1. Nájdeme stred tabuľky.
  2. Porovnáme hľadaný prvok so stredovým prvkom.
  3. Ak je hľadaný prvok menší, pokračujeme v ľavej polovici. Ak je väčší, pokračujeme v pravej polovici.
  4. Postup opakujeme, kým prvok nenájdeme alebo tabuľka nebude prázdna.

Výhody: Veľmi rýchle vyhľadávanie. Nevýhody: Tabuľka musí byť usporiadaná.

Časová zložitosť:

  • Best-case: O(1)
  • Average-case: O(log n)
  • Worst-case: O(log n)

Hašovanie a Hašovacie Tabuľky

Hašovanie je technika, pri ktorej sa prvok pomocou hašovacej funkcie priamo mapuje na pozíciu v tabuľke (hašovacia tabuľka). To umožňuje veľmi rýchle operácie.

Postup:

  1. Na kľúč aplikujeme hašovaciu funkciu.
  2. Funkcia vypočíta index v tabuľke.
  3. Na tomto mieste uložíme alebo vyhľadáme prvok.

Výhody: Veľmi rýchle operácie (takmer konštantný čas, O(1)). Nevýhody: Môžu vzniknúť kolízie.

Hašovacia Funkcia a Kolízie

Hašovacia funkcia transformuje kľúč na index tabuľky, napríklad h(k) = k mod m (kde k je kľúč a m je veľkosť tabuľky). Dobrá hašovacia funkcia rovnomerne rozdeľuje prvky, minimalizuje kolízie a je rýchla na výpočet.

Kolízia nastáva, keď dva rôzne kľúče majú rovnaký index. Jedným zo spôsobov riešenia kolízií je hašovanie reťazením, kde každá pozícia tabuľky obsahuje zoznam prvkov. Ak nastane kolízia, nový prvok sa pridá do zoznamu na danom indexe.

Často Kladené Otázky o Dynamických Dátových Štruktúrach a Algoritmoch

Prečo sú dynamické dátové štruktúry dôležité?

Dynamické dátové štruktúry sú kľúčové, pretože umožňujú programom prispôsobiť sa meniacemu sa objemu dát počas ich behu. Nemusíme vopred vedieť presný počet prvkov, čo výrazne zjednodušuje správu pamäte a zvyšuje flexibilitu aplikácií.

Aký je rozdiel medzi jednosmerným a dvojito spájaným zoznamom?

Jednosmerný spájaný zoznam má každý prvok (vrchol) s odkazom len na nasledujúci prvok, takže sa ním dá prechádzať iba dopredu. Dvojito spájaný zoznam má v každom vrchole odkazy na predchádzajúci aj nasledujúci prvok, čo umožňuje prechádzanie v oboch smeroch – dopredu aj dozadu.

Kedy použiť Merge Sort a kedy Quick Sort?

Merge Sort je stabilný a má garantovanú časovú zložitosť O(n log n) aj v najhoršom prípade, ale vyžaduje dodatočnú pamäť O(n), čo ho robí vhodným pre externé triedenie (dáta na disku). Quick Sort je v priemere veľmi rýchly a pamäťovo efektívnejší (O(log n) pre rekurziu), ale v najhoršom prípade môže mať zložitosť O(n²). Je preferovaný pre interné triedenie (dáta v RAM).

Čo je to asymptotická zložitosť a prečo je dôležitá?

Asymptotická zložitosť opisuje, ako sa čas alebo pamäť algoritmu mení s rastúcou veľkosťou vstupu (n). Je dôležitá, pretože nám umožňuje porovnávať efektívnosť algoritmov a predpovedať ich správanie pre veľmi veľké vstupy, pričom ignoruje konštantné faktory a detaily implementácie. Najčastejšie sa vyjadruje pomocou notácie O (Big O).

Ako súvisí Huffmanov kód so stromami?

Huffmanov kód používa binárny strom (Huffmanov strom) na generovanie optimálnych kódov pre znaky. Cesta od koreňa k listu v strome určuje binárny kód pre daný znak, pričom frekventovanejšie znaky sú bližšie ku koreňu a majú kratšie kódy. To vedie k efektívnejšej kompresii dát.

Sign up to access full content

Create a free account to unlock all study materials, take interactive tests, listen to podcasts and more.

Create free account

Súvisiace témy