[[oktatas:programozás|< Programozás]]
====== Elemi adatszerkezetek ======
* **Szerző:** Sallai András
* Copyright (c) 2011, Sallai András
* Szerkesztve: 2011, 2014, 2021, 2024
* Licenc: [[https://creativecommons.org/licenses/by-sa/4.0/|CC BY-SA 4.0]]
* Web: https://szit.hu
===== Vermek =====
A verem, angolul stack. A veremben több adatot tárolhatunk,
de mindig csak az utoljára betett adatot vehetjük ki.
Az alábbiakban egy tömbön megvalósított verem sematikus ábráját látjuk, ahol
számokat tárolunk.
{{:oktatas:programozás:verem.png|}}
Itt az utoljára betett szám az 50-es, ezt tudjuk kivenni elsőként.
Működése alapján angolosan **LIFO**-nak nevezzük az adatszerkezetet; a **Last In First Out** szavakból.
Java nyelven:
import java.util.ArrayList;
public class SimpleStack {
private ArrayList elements;
public SimpleStack() {
elements = new ArrayList<>();
}
public void push(T elem) {
elements.add(elem);
}
public T pop() {
return elements.remove(elements.size()-1);
}
public int size() {
return elements.size();
}
}
===== Sorok =====
A sorok vagy angolul queue. Az elsőként betett elemet tudjuk kivenni elsőként
a sorból. Működése alapján, angolosan ezt **FIFO** adatszerkezetnek nevezzük;
A **First In First Out** szavakból.
{{:oktatas:programozás:sor.png|}}
import java.util.ArrayList;
public class SimpleQueue {
private ArrayList elements;
public SimpleQueue() {
elements = new ArrayList<>();
}
public void enqueue(T elem) {
elements.add(elem); // Hozzáadunk egy elemet a sor végéhez
}
public T dequeue() {
if (elements.isEmpty()) {
throw new RuntimeException("A sor üres, nem lehet kivenni elemet!");
}
return elements.remove(0); // Kivesszük a sor elejéről az első elemet
}
public int size() {
return elements.size(); // Visszaadja az aktuális elemek számát a sorban
}
public boolean isEmpty() {
return elements.isEmpty(); // Ellenőrzi, hogy a sor üres-e
}
}
===== Láncolt listák =====
Az objektumok lineáris sorrendben követik egymást.
Minden adathoz tartozik egy mutató is. A mutató
mindig a következő adatra mutat.
Az utolsó adat mutatója vagy nem mutat sehova, vagy az első
elemre mutat. Ha nem mutat sehova ezt egy NIL céllal szokás jelölni.
{{:oktatas:programozás:lancolt_lista_1.png|}}
Egy elem leírása Java nyelven:
class Elem {
Object adat;
Elem kovetkezo;
}
C nyelven:
struct telem {
Object adat;
struct telem *kovetkezo;
}
{{:oktatas:programozás:lancolt_lista_ketiranyban_lancolt.png|}}
Egy elem leírása Java nyelven
class Elem {
Object adat;
Elem elozo;
Elem kovetkezo;
}
===== Gráfok =====
Pontok halmaza, amelyeket vonalakkal kötünk összes.
A pontokat csúcsoknak, a vonalakat éleknek nevezzük.
{{:oktatas:programozás:graf_001.png|}}
A gráfok csúcsokból és a csúcsokat összekötő élekből állnak.
{{:oktatas:programozás:graf_002.png|}}
Ha a csúcspontok számozottak, vagy más módon jelöltek, akkor
címkézett gráfról beszélünk.
{{:oktatas:programozás:graf_003_cimkezett.png|}}
Ha az élek nyílhegyben végződnek, akkor irányított gráfról beszélünk.
{{:oktatas:programozás:graf_004_iranyitott.png|}}
Ha a gráfunk körmentes, akkor fagráfnak nevezhetjük.
{{:oktatas:programozás:graf_005_fagraf.png|}}
Ha több fagráfunk is van, nevezhetjük erdőnek.
{{:oktatas:programozás:graf_006_erdo.png|}}
===== Fák =====
==== A fákról ====
A fák előnye a listákkal szemben, hogy gyorsabb a bejárásuk.
A gráfelmélet alapján a fa:
* körmentes (két elem között csak egyetlen út létezik)
* összefüggő egyszerű gráfok
A számítástechnikában általában gyökeres fákkal dolgozunk. Ezt figyelembe véve a meghatározása következő lehet:
Csomópontok halmaza, amit élek kötnek össze, a következő feltételekkel:
* létezik egy kitüntetett csomópont a gyökér
* minden a gyökértől különböző elemet egy éllel kötünk a szülőjéhez
* bármely nem gyökér elemtől a szülőkön keresztül, eljuthatunk a gyökérig
A közbenső elemeket ha gyökérként jelöljük meg, az alatta elhelyezkedő elemekkel részfát alkotnak.
{{:oktatas:programozás:002_fa_reszei.png|}}
A fa magasság a fa szintjeinek száma.
==== A bináris fa ====
Minden elemnek **legfeljebb két gyermekeleme** van.
{{:oktatas:programozás:003_binarisfa.png|}}
{{:oktatas:programozás:004_binarisfa.png|}}
==== Nem bináris ====
Előfordulhat kettőnél több leágazás.
{{:oktatas:programozás:001_fa.png|}}
==== Kiegyensúlyozott fák ====
Kiegyensúlyozott fáról beszélünk, ha az egyes szinteken a részfák magasságágának ingadozása nem nagyobb egynél.
{{:oktatas:programozás:005_kiegyensulyozottfa.png|}}
{{:oktatas:programozás:006_kiegyensulyozatlanfa.png|}}
{{:oktatas:programozás:007_tokeletesenkiegyensulyozottfa.png|}}
==== Bináris keresőfák ====
Bináris keresőfáról beszélünk, ha minden szülőre igaz, hogy
balra a nála kisebb elemek helyezkednek el, jobb a nála nagyobb elemek.
{{:oktatas:programozás:008_binariskeresofa_1.png|}}
{{:oktatas:programozás:009_binariskeresofa_2.png|}}
{{:oktatas:programozás:008_binariskeresofa_3.png|}}
Bináris kereső fa építése:
* elhelyezzük az első elemet gyökérként
* ha következő elem kisebb mint az előző, akkor
* a gyökérelemtől balra helyezzük el
* ellenben
* jobbra helyezzük el
* A már bevitt elemeket végigjárva, ha csomópontnál kisebb akkor
* balra megyünk
* ellenben jobbra
==== Műveletek fákkal ====
* beszúrás
* törlés
{{:oktatas:programozás:010_beszurasfaba.png|}}
{{:oktatas:programozás:011_torlesfabol.png|}}
==== Egy elem leírása Java nyelven ====
class Elem {
Object adat;
Elem szulo;
Elem bal;
Elem jobb;
}
==== A fa bejárása ====
A fák bejárásának lehetséges módjai:
* szélességi bejárás
* mélységi bejárás
Mélységi bejárás háromféle sorrendje az informatikában:
* preorder bejárás
* inorder bejárás
* postorder bejárás
{{:oktatas:programozás:fakbejarasa.png|}}
==== Preorder bejárás ====
* a gyökér elem
* majd a baloldali részfa preorder bejárása
* jobboldali részfa preorder bejárása
{{:oktatas:programozás:fapreorderbejaras.png|}}
Preorder bejárás java nyelven:
static void preorder(Elem elem) {
if(elem != null) {
System.out.println(elem.adat);
preorder(elem.bal);
preorder(elem.jobb);
}
}
==== Inorder bejárás ====
* baloldal részfa inorder bejárása
* gyökér elem
* jobboldali részfa inorder bejárása
{{:oktatas:programozás:fainorderbejaras.png|}}
Java megvalósítás:
static void inorder(Elem elem) {
if(elem != null) {
inorder(elem.bal);
System.out.printf("%c ", elem.adat);
inorder(elem.jobb);
}
}
==== Posztorder bejárás ====
* baloldali részfa posztorder bejárása
* jobboldali részfa posztorder bejárása
* végül a gyökér elem
{{:oktatas:programozás:fapostorderbejaras.png|}}
Java megvalósítás:
static void postorder(Elem elem) {
if(elem != null) {
postorder(elem.bal);
postorder(elem.jobb);
System.out.printf("%c ", elem.adat);
}
}
==== Szélességi bejárás ====
{{:oktatas:programozás:szelessegibejaras.png|}}
===== Irodalom =====
==== Könyvek ====
* Thomas H. Cormen, Charles E. Leierson, Ronald L. Rivest, Clifford Stein: Új algoritmusok
==== Linkek ====
* http://www.dkrmg.sulinet.hu/~lutter/szakkor/ (2021)
* http://hu.wikibooks.org/wiki/Programoz%C3%A1s/Algoritmusok (2021)
===== Függelék =====
==== Láncolt lista példa ====
{{:oktatas:programozás:lancolt_lista_programozasi_nyelvben.png|}}
class Szam {
Integer szam;
Szam kov;
}
public class Mutatok {
public static void main(String[] args) {
Szam elso = new Szam();
Szam akt = new Szam();
elso=akt;
Szam uj;
uj = new Szam();
uj.szam = 27;
akt.kov = uj;
akt = uj;
uj = new Szam();
uj.szam = 45;
akt.kov = uj;
akt = uj;
uj = new Szam();
uj.szam = 82;
akt.kov = uj;
akt = uj;
//Kiíratás
akt = elso.kov;
System.out.println("Kiíratás");
do {
System.out.println(akt.szam);
akt = akt.kov;
} while (akt != null);
}
}