Programozási Paradigmák. és Technikák



Hasonló dokumentumok
Generikus Típusok, Kollekciók

Láncolt lista Bináris keresőfa Gráf Hasító táblázat. Programozás II. labor 2. rész (Adatszerkezetek)

.Net adatstruktúrák. Készítette: Major Péter

OOP: Java 8.Gy: Abstract osztályok, interfészek

OOP #14 (referencia-elv)

Elemi adatszerkezetek

és az instanceof operátor

Java VIII. Az interfacei. és az instanceof operátor. Az interfészről általában. Interfészek JAVA-ban. Krizsán Zoltán

List<String> l1 = new ArrayList<String>(); List<Object> l2 = l1; // error

JAVA PROGRAMOZÁS 2.ELŐADÁS

Gráfok 2. Legrövidebb utak, feszítőfák. Szoftvertervezés és -fejlesztés II. előadás. Szénási Sándor

Osztályok. 4. gyakorlat

Objektumorientált programozás C# nyelven

Programozás II. 3. gyakorlat Objektum Orientáltság C++-ban

3. Osztályok II. Programozás II

Programozás II. labor

C# Zero.4 Introducing Visual C# 2.0

Programozás II. 2. gyakorlat Áttérés C-ről C++-ra

Algoritmusok és adatszerkezetek gyakorlat 06 Adatszerkezetek

Programozási technológia

A számítástudomány alapjai. Katona Gyula Y. Számítástudományi és Információelméleti Tanszék Budapesti Műszaki és Gazdaságtudományi Egyetem

Objektumorientált Programozás VI.

Interfészek. PPT 2007/2008 tavasz.

C# Nyelvi Elemei. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) C# Nyelvi Elemei / 18

1. Template (sablon) 1.1. Függvénysablon Függvénysablon példányosítás Osztálysablon

Bánsághi Anna 2014 Bánsághi Anna 1 of 33

Generikus osztályok, gyűjtemények és algoritmusok

5/1. tétel: Optimalis feszítőfák, Prim és Kruskal algorithmusa. Legrövidebb utak graphokban, negatív súlyú élek, Dijkstra és Bellman Ford algorithmus.

Már megismert fogalmak áttekintése

Adatszerkezetek 7a. Dr. IványiPéter

Java programozási nyelv 5. rész Osztályok III.

Bevezetés a programozásba Előadás: Tagfüggvények, osztály, objektum

Programozási nyelvek Java

Programozás BMEKOKAA146. Dr. Bécsi Tamás 5. előadás

Számítástechnika II. BMEKOKAA Előadás. Dr. Bécsi Tamás

Szoftvertechnolo gia gyakorlat

Web-technológia PHP-vel

Mi a különbség az extends és az implements között. Mikor melyiket kell használni? Comperable-t megvalósító oasztályokban össze lehet hasonlitani

OOP: Java 11.Gy: Enumok, beágyazott osztályok. 13/1 B ITv: MAN

C# osztályok. Krizsán Zoltán

Programozási nyelvek II.: JAVA, 3. gyakorlat

Java VI. Miskolci Egyetem Általános Informatikai Tanszék. Utolsó módosítás: Ficsor Lajos. Java VI.: Öröklődés JAVA6 / 1

Ugrólisták. RSL Insert Example. insert(22) with 3 flips. Runtime?

Programozás I. Első ZH segédlet

Java VI. Egy kis kitérő: az UML. Osztály diagram. Általános Informatikai Tanszék Utolsó módosítás:

Collections. Összetett adatstruktúrák

Számítástechnika II. BMEKOKAA Előadás. Dr. Bécsi Tamás

Programozási nyelvek Java

Bánsághi Anna

Java és web programozás

Speciális adatszerkezetek. Programozás alapjai II. (8. ea) C++ Tömbök. Tömbök/2. N dimenziós tömb. Nagyméretű ritka tömbök

Adatszerkezetek és algoritmusok

BME MOGI Gépészeti informatika 8.

Java és web programozás

Programozási Paradigmák és Technikák

OOP: Java 8.Gy: Gyakorlás

A szemantikus elemzés helye. A szemantikus elemzés feladatai. A szemantikus elemzés feladatai. Deklarációk és láthatósági szabályok

Szoftvertechnológia alapjai Java előadások

Programozási nyelvek Java

Pelda öröklődésre: import java.io.*; import java.text.*; import java.util.*; import extra.*;

Java és web programozás

Programozási nyelvek Java

Programozás alapjai II. (7. ea) C++ Speciális adatszerkezetek. Tömbök. Kiegészítő anyag: speciális adatszerkezetek

Programozási alapismeretek 4.

Algoritmusok és adatszerkezetek gyakorlat 07

A C# programozási nyelv alapjai

Objektumorientált programozás C# nyelven

Öröklés és Polimorfizmus

Programozás alapjai II. (7. ea) C++

Programozási nyelvek II. JAVA EA+GY 1. gyakolat

OOP: Java 5.Gy: Osztály, referencia, konstruktor

C# nyelv alapjai. Krizsán Zoltán 1. Objektumorientált programozás C# alapokon tananyag. Általános Informatikai Tanszék Miskolci Egyetem

A C programozási nyelv V. Struktúra Dinamikus memóriakezelés

Programozási nyelvek II.: JAVA

Apple Swift kurzus 3. gyakorlat

Visual C++ osztály készítése, adattagok, és metódusok, láthatóság, konstruktor, destruktor. Objektum létrehozása, használata, öröklés.

Vizuális és eseményvezérelt programozás , II. félév BMF NIK

Gráfalgoritmusok ismétlés ősz

Pénzügyi algoritmusok

Fák Témakörök. Fa definíciója. Rekurzív típusok, fa adatszerkezet Bináris keresőfa, bejárások Bináris keresőfa, módosítás B-fa

Programozási nyelvek II.: JAVA, 4. gyakorlat

OOP: Java 4.Gy: Java osztályok

Helyes-e az alábbi kódrészlet? int i = 1; i = i * 3 + 1; int j; j = i + 1; Nem. Igen. Hányféleképpen lehet Javaban megjegyzést írni?

Miután létrehoztuk, szeretnénk neki beszédesebb nevet adni. A név változtatásához a következőt kell tenni:

Programozási nyelvek II.: JAVA, 4. gyakorlat

Programozás I. 3. gyakorlat. Szegedi Tudományegyetem Természettudományi és Informatikai Kar

A programozás alapjai 1 Rekurzió

Információs Technológia

Programozási nyelvek Java

Memóriakezelés, dinamikus memóriakezelés

1. Mi a fejállományok szerepe C és C++ nyelvben és hogyan használjuk őket? 2. Milyen alapvető változókat használhatunk a C és C++ nyelvben?

VI. turnus (Kontaktnapok: szerda) Képzés időtartama: augusztus október 15.

Java II. I A Java programozási nyelv alapelemei

Széchenyi István Egyetem. Programozás III. Varjasi Norbert

Tuesday, March 6, 12. Hasító táblázatok

Gráfok 1. Tárolási módok, bejárások. Szoftvertervezés és -fejlesztés II. előadás. Szénási Sándor

Programozás. C++ osztályok. Fodor Attila. Pannon Egyetem Műszaki Informatikai Kar Villamosmérnöki és Információs Rendszerek Tanszék

Algoritmusok és adatszerkezetek II.

Az osztályok csomagokba vannak rendezve, minden csomag tetszőleges. Könyvtárhierarhiát fed: Pl.: java/util/scanner.java

Gráfok. Programozás II. előadás. Szénási Sándor.

Átírás:

Programozási Paradigmák Láncolt Lista Generikus osztályok Láncolt Lista megvalósítása Bináris keresőfa (BST) BST megvalósítása Gráfok Dijkstra algoritmus Kruskal algoritmus és Technikák szabo.zsolt@nik.uni-obuda.hu 1

Programozási Paradigmák Láncolt Lista Generikus osztályok Erdélyi Krisztina Láncolt Lista megvalósítása Bináris keresőfa (BST) BST megvalósítása Gráfok Dijkstra algoritmus Kruskal algoritmus és Technikák szabo.zsolt@nik.uni-obuda.hu 2

Generikus Osztályok Generikus osztályok Generikus metódusok Megszorítások Statikus tagok Öröklés A generikus osztályok működése a.net-ben szabo.zsolt@nik.uni-obuda.hu 3

Bevezetés feladat Cél: személyeket tárolóhalmaz létrehozása, egy elemet egyszer tartalmazhat, a lehető legáltalánosabb módon Milyen elemekből álljon a halmaz? Személy akkor a kutya-klubhoz át kell írni A személy és a kutya őse ez biztos, hogy elég általános? Object(mindennek az őse) -ez lehet megoldás ArrayList,.NET1, csak object-et tárol, állandó castolás A típust adjuk meg paraméterként, így elég a deklarációban megadni a konkrét típust Vizsgáljuk meg ezt közelebbről! szabo.zsolt@nik.uni-obuda.hu 4

Generics Más néven sablon vagy template Paraméterezett típus vagy metódus Minden egyes paraméter egy még meg nem határozott típus helye Az osztály tervezésekor csak T néven hivatkozok a típusra, csak az osztály példányosításakor definiálom, hogy ez a T pontosan mi szabo.zsolt@nik.uni-obuda.hu 5

Paraméterezett típusok A paraméter a típus fejrészében helyezkedik el class MyGenericClass<T> { } Deklarációnál és példányosításkor az aktuális típus kerül a paraméter helyére MyGenericClass<int>mgcINT= new MyGenericClass<int>(); A generic-ek tipikusan gyűjtemények létrehozásához valók, mivel a gyűjtemények több típussal is használhatók szabo.zsolt@nik.uni-obuda.hu 6

Generikus gyűjtemények ArrayList object típust tárol, állandó castolás, elavult List<T>: Add(), Insert(), Remove(), RemoveAt(), Reverse(), [], Clear(), Contains(), Count Queue<T>: Enqueue(), Dequeue(), Peek(), Clear(), Contains(), Count Stack<T>: Push(), Pop(), Peek(), Clear(), Contains(), Count Lehetőség van több típus használatára: class valami<t,u> { } Dictionary<T, U>: Add(), Remove(), TryGetValue(), Keys, Values, Clear(), ContainsKey(), ContainsValue(), Count szabo.zsolt@nik.uni-obuda.hu 7

Saját generikus osztály létrehozása szabo.zsolt@nik.uni-obuda.hu 8

Generikus osztály használata szabo.zsolt@nik.uni-obuda.hu 9

Paraméterezett típus inicializálása object valtozo=null; int valtozo=0; string valtozo= ; T valtozo =???? Nem tudható, hogy érték vagy referencia típusú-e a paraméter Megoldás: default expression Referenciánál null-t ad vissza Érték típusnál bitenkénti nullát T valtozo = default(t); szabo.zsolt@nik.uni-obuda.hu 10

Megszorítások Lefordulnak a következő kódok? Ha nem, akkor mi a megoldás? Csak annyit tudhatunk a T típusról biztosan, hogy a System.Object-ből származik Ezért ennek megfelelően viselkedik szabo.zsolt@nik.uni-obuda.hu 11

Interfész megszorítás class MyClass2<T> { public void Iterate(T data) { foreach (object item in data) { Console.WriteLine(item); } } } class MyClass2<T> where T : IEnumerable<T>{ public void Iterate(T data) { foreach (object item in data) { Console.WriteLine(item); } } } OK Nem biztos, hogy T felsorolható! (A foreach ciklus akkor működik saját típuson, ha a saját típus megvalósítja az IEnumerable interfészt, ld. később) (Azonos módon interface megszorítással lehet azt garantálni, hogy a T típusnak van egy adott metódusa) szabo.zsolt@nik.uni-obuda.hu 12

Konstruktor megszorítás class MyClass<T> { T obj = new T(); } Nem biztos, hogy T-nek van alapértelmezett konstruktora! class MyClass<T> where T:new() { T obj = new T(); } OK szabo.zsolt@nik.uni-obuda.hu 13

Művelet megszorítás??? class Arithmetic<T>{ public T Cubed(T number){ return number * number * number; } } class Arithmetic<T> where T : System.Int32{ public T Cubed(T number){ return number * number * number; } } Nem biztos, hogy T-n értelmezett a szorzás! Érték és primitív típusok nem lehetnek megszorítások! Súlyos korlátja a generics használatának, hogy standard operátorok az érték típusokkal nem használhatók. szabo.zsolt@nik.uni-obuda.hu 14

A Generic korlátja class Program2 { public T Min<T>(T a, T b) where T : IComparable<T> { if (a<b) return a; else return b; } } class Program { public T Min<T>(T a, T b) where T : IComparable<T> { if (a.compareto(b)<0) return a; else return b; } } A standard operátorok így sem használhatók. szabo.zsolt@nik.uni-obuda.hu 15

Megszorítások összefoglalása A megszorítások a típus paraméterektől elvárt viselkedést írják le A where kulcsszóval vezetjük be Típusnál és metódusnál is használhatók Fajtáik: Leszármazott (where T : Személy) Interfész (where T: IEnumerable<T>) Érték típus (where T: struct) Referencia típus (where T: class) Konstruktor (where T: new()) Az alábbi típusok nem lehetnek megszorításban: Lezárt osztályok Primitív típusok System.Array System.Delegate System.Enum System.ValueType szabo.zsolt@nik.uni-obuda.hu 16

Generikus metódus Tartozhat generikus vagy nem generikus típushoz Azért, mert az osztály generikus, a metódus még nem A metódus generikus, ha saját típusparamétere(i) van(nak) A típusparaméter megjelenhet visszatérési értékként vagy a paraméterlistában szabo.zsolt@nik.uni-obuda.hu 17

Generikus metódusok meghívása A metódus meghívásakor a paraméterek típusa adja meg a típusparaméter aktuális értékét: int i=min(2, 3); //egészek float f=min(2.0, 3.0); //valósak Két azonos nevű és szignatúrájú metódus nem lehet És ha T=int? Ellentmondás esetén a nem-generikus eljárás hívódik meg Ha két generikus metódus van különbözőgenerikus paraméterrel pl. Method(T arg), Method(U arg), és T és U konkrétan ugyanaz, akkor a metódus meghívásánál jelez hibát. szabo.zsolt@nik.uni-obuda.hu 18

Statigus tagok generikus osztályokban class MyGenericClass<T> { private static int counter = 0; public MyGenericClass() { counter++; } public static void Count() { Console.WriteLine(counter); } } szabo.zsolt@nik.uni-obuda.hu 19

Statikus tagok generikus osztályokban A statikus tagok eléréséhez be kell helyettesíteni egy konkrét típust a paraméterbe MyGenericClass<int>.Count(); Különbözőbehelyettesített típusokhoz különbözőstatikus tagok tartoznak A statikus konstruktor implicit meghívódik, és a behelyettesített típusnak megfelelően inicializálja a statikus mezőket szabo.zsolt@nik.uni-obuda.hu 20

Generikus osztályok az öröklésben Generikus osztály lehet őse generikus és nem generikus osztálynak Generikus osztály származhat generikus vagy nem generikus osztályból De mindkét állítás csak bizonyos esetekben igaz! Az utód példányosításakor a típusparaméterek értékét mindenképpen meg kell határozni Ha Derived<T> : BaseGeneric<T>, és newderived<int>() a T típus mindkét osztályban int lesz. Ha Derived : BaseGeneric<T>, és newderived() az ős T típusparamétere nincs definiálva, NEM MEGENGEDETT Ha Derived<T> : BaseGeneric<U>, és newderived<int>() az U típus nincs definiálva az ősosztályban, NEM MEGENGEDETT szabo.zsolt@nik.uni-obuda.hu 21

Generikus osztályok az öröklésben Melyik eset lehetséges? szabo.zsolt@nik.uni-obuda.hu 22

Generikus osztályok az öröklésben és a.net-ben A típusra vonatkozóős osztálybeli megszorításokat az utódosztályban meg kell ismételni Az utódosztály tartalmazhat további megszorításokat Nem nyelvspecifikus, minden felügyelt nyelvben elérhető A köztes kódra valófordítás során metaadatok és a generic-ekre vonatkozómsil kód áll elő, a JIT fordítás során történik meg a konkrét típusok behelyettesítése szabo.zsolt@nik.uni-obuda.hu 23

Programozási Paradigmák Láncolt Lista Generikus osztályok Láncolt Lista megvalósítása Bináris keresőfa (BST) BST megvalósítása Gráfok Dijkstra algoritmus Kruskal algoritmus és Technikák szabo.zsolt@nik.uni-obuda.hu 24

IEnumerable / IEnumerator A foreach ciklus akkor működik saját típuson, ha a saját típus megvalósítja a IEnumerable<T> interfészt Ez az interfész előírja a GetEnumerator() eljárást, ami visszaad egy olyan objektumpéldányt, ami megvalósítja az IEnumerator<T> interfészt Az IEnumerator<T> előírja a következőműveleteket: Aktuális elem olvasása (Current), következőelemre mozgás (MoveNext()), visszaállás az első előtti elemre (Reset()) lista bejárása Mindegyik interfész előírja a nemgenerikus (object) változatot is Saját enumerator helyett bizonyos esetben meglévőenumeratort is használhatunk, ha olyan struktúrába rendezhetőek az adatok, ahol ez elérhető(tömb / List<T>) szabo.zsolt@nik.uni-obuda.hu 25

Láncolt Lista Egyszeresen láncolt, ciklikus, kétszeresen láncolt listák (ld. Ea.) Strázsa-elemes, rendezett láncolt listák (ld. Ea.) Órai feladat: telefonkönyv-bejegyzések (név, cím, telefonszám) egyirányú, nem rendezett láncolt listába fejtése ZH: egyéb láncolás is lehetséges szabo.zsolt@nik.uni-obuda.hu 26

A fejlesztés menete 1. Generikus osztályként megtervezzük a ListaElem<T> osztályt, amely egy T típusúreferenciát tárol, valamint egy referenciát a következő listaelemre 2. Generikus osztályként megtervezzük a Lista<T> osztályt, amely tárol egy referenciát az elsőlistaelemre, emellett itt implementáljuk az eljárásokat is: a) public void Beszúr(T elem) b) public T Keres(T mitkeres, out bool talalt) c) public bool Töröl(T elem) d) public bool Töröl(int index) e) Cél: a lista osztályt be lehessen járni foreach ciklussal 3. A foreach ciklus működése miatt tervezünk egy saját felsorolót 4. Megtervezzük a bejegyzés osztályt, amit ténylegesen tárolni akarunk 5. Tesztprogram írása szabo.zsolt@nik.uni-obuda.hu 27

ListaElem<T> T típusúadatot tárol + egy referenciát a következőelemre Tulajdonságok, konstruktor, ToString() Lista<T> + ListaEnumerator<T> ListaElem<T> Elso; + konstruktor? public void Beszúr(T elem) PPT előadás public T Keres(T mitkeres, out bool talalt) PPT előadás, p.elem.equals(mitkeres) public bool Töröl(T elem) PPT előadás, ugyanúgy Equals() public bool Töröl(int index) index szerinti törlés Cél: a lista osztályt be lehessen járni foreach ciklussal saját felsoroló készítése: Current, MoveNext(), Reset() szabo.zsolt@nik.uni-obuda.hu 28

Telefonkönyv bejegyzés Név + Cím + Telefonszám Konstruktor + ToString() Speciális Equals() : rész-egyenlőség visszaadott értéke is true Tesztprogram Lista<Bejegyzes> telefonszámok = new Lista<Bejegyzes>(); Bejegyzes keresett, talalt; bool van; szabo.zsolt@nik.uni-obuda.hu 29

Tesztprogram szabo.zsolt@nik.uni-obuda.hu 30

Tesztprogram szabo.zsolt@nik.uni-obuda.hu 31

Programozási Paradigmák Láncolt Lista Generikus osztályok Láncolt Lista megvalósítása Bináris keresőfa (BST) BST megvalósítása Gráfok Dijkstra algoritmus Kruskal algoritmus és Technikák szabo.zsolt@nik.uni-obuda.hu 32

Bináris keresőfa szabo.zsolt@nik.uni-obuda.hu 33

A fejlesztés menete 1. Generikus osztályként megtervezzük a csucs<t> osztályt, amely egy T típusúreferenciát tárol, valamint egy referenciát a jobb és a bal oldali gyermek-elemre 2. Generikus osztályként megtervezzük a fa<t> osztályt, amely tárol egy referenciát a gyökérelemre, valamint azt, hogy milyen bejárást akarunk használni (szélességi, mélységi, inorder, preorder, postorder), emellett itt implementáljuk az eljárásokat is: a) public bool bennevan(t elem) b) public void beszur(t ujelem) c) public bool torol(t x) d) Cél: a fát be lehessen járni foreach ciklussal 3. A foreach ciklus működéséhez az éppen kiválasztott bejárást hívjuk meg, és a produkált lista felsorolóját ( List<T>.GetEnumerator() ) használjuk fel 4. Tesztprogram írása, amiben a fa számokat tárol szabo.zsolt@nik.uni-obuda.hu 34

Fejlesztési sajátosságok Szélességi bejárás sor, mélységi bejárás verem adatszerkezettel InOrder/PreOrder/PostOrder bejárás rekurzióval Az előadáson bemutatott eljárások egyik paramétere az aktuális csúcs (pl. Függvény Beszúrás(címszerint p, újkulcs) ), és az első meghíváskor a p paraméter értéke a gyökér OOP megközelítésben a publikus eljárásainkban az aktuális csúcs nem szerepel, pl. public void beszur(t ujelem) A publikus eljárás nem-publikus eljárásra hivatkozik, pl. private priv_beszur(ref FRoot, ujelem) Fontos kérdés: miért kell a paraméternél ref kulcsszó, amikor már úgyis referencia típus a csucs<t>? OOP tárgy, paraméter-átadási módok szabo.zsolt@nik.uni-obuda.hu 35

Ref.típusok cím szerinti paraméterátadása static void tombkez1(ref int[] arr) { arr[1] = 42; } static void tombkez2(ref int[] arr) { arr = new int[3] { 23, 23, 23 }; } ÓE-NIK, 2011 36

Ref.típusok cím szerinti paraméterátadása static void Main(string[] args) { int[] t = { 3, 4, 5 }; tombkez1(ref t); tombkez2(ref t); } Híváskor a változócímérőlmásolat képződik, és a CÍMkerül át paraméterként a hívott eljárásokba Referenciára mutató referencia A hívott eljárásokban ezt a változót és a hivatkozott memóriaterületet is lehet módosítani ÓE-NIK, 2011 37

Ref.típusok cím szerinti paraméterátadása Memória cím1 t cím2 cím2 3 4 5 int[]t= {3, 4, 5}; ÓE-NIK, 2011 38

Ref.típusok cím szerinti paraméterátadása Memória cím1 t cím2 cím3 arr cím1 cím2 3 4 5 int[]t= {3, 4, 5}; tombkez1(t); ÓE-NIK, 2011 39

Ref.típusok cím szerinti paraméterátadása Memória cím1 t cím2 cím3 arr cím1 cím2 3 42 5 int[]t= {3, 4, 5}; tombkez1(t); arr[1]=42; Teljesen mindegy, hogy hány referencián keresztül van az értékadás, mindig a megfelelőértékre történik a hivatkozás! ÓE-NIK, 2011 40

Ref.típusok cím szerinti paraméterátadása Memória cím1 t cím2 cím3 arr cím1 cím2 3 42 5 cím4 23 23 23 int[]t= {3, 4, 5}; tombkez1(t); arr[1]=42; tombkez2(t); arr=new int[3] { 23, 23, 23}; ÓE-NIK, 2011 41

Ref.típusok cím szerinti paraméterátadása Memória cím1 t cím4 cím3 arr cím1 cím2 3 42 5 cím4 23 23 23 int[]t= {3, 4, 5}; tombkez1(t); arr[1]=42; tombkez2(t); arr=new int[3] { 23, 23, 23}; A paraméterül adott változót cseréltem le ÓE-NIK, 2011 42

Fejlesztési sajátosságok Fontos kérdés: miért kell a paraméternél a ref kulcsszó, amikor már úgyis referencia típus a csucs<t>? Válasz: hiába referencia típus, a cél az, hogy a hívott eljárásból a fa szerkezetét tudjam módosítani. Ehhez nem csak a paraméterül adott csúcs adatait kell módosítanom, hanem törlésnél/beszúrásnál közvetlenül a paraméterül adott csúcsot kell cserélni ehhez kell a referencia típus referencia szerinti paraméterátadása A csúcs osztályban a gyermek-elemekhez ne csináljuk tulajdonságot, maradjanak publikus adattagok ez nem szép megoldás, de ha a gyermekcsúcsokat referenciaként akarom továbbadni, akkor erre szükség van szabo.zsolt@nik.uni-obuda.hu 43

A fejlesztés menete 1. Generikus osztályként megtervezzük a csucs<t> osztályt, amely egy T típusúreferenciát tárol, valamint egy referenciát a jobb és a bal oldali gyermek-elemre 2. Generikus osztályként megtervezzük a fa<t> osztályt, amely tárol egy referenciát a gyökérelemre, valamint azt, hogy milyen bejárást akarunk használni (szélességi, mélységi, inorder, preorder, postorder), emellett itt implementáljuk az eljárásokat is: a) public bool bennevan(t elem) b) public void beszur(t ujelem) c) public bool torol(t x) d) Cél: a fát be lehessen járni foreach ciklussal 3. A foreach ciklus működéséhez az éppen kiválasztott bejárást hívjuk meg, és a produkált lista felsorolóját ( List<T>.GetEnumerator() ) használjuk fel 4. Tesztprogram írása, amiben a fa számokat tárol szabo.zsolt@nik.uni-obuda.hu 44

Tesztprogram I. szabo.zsolt@nik.uni-obuda.hu 45

Tesztprogram II. szabo.zsolt@nik.uni-obuda.hu 46

Tesztprogram III. szabo.zsolt@nik.uni-obuda.hu 47

Programozási Paradigmák Láncolt Lista Generikus osztályok Láncolt Lista megvalósítása Bináris keresőfa (BST) BST megvalósítása Gráfok Dijkstra algoritmus Kruskal algoritmus és Technikák szabo.zsolt@nik.uni-obuda.hu 48

Gráfok & Dijkstra algoritmus Gráf: csomópontok és a csomópontokat összekötő élek halmaza Jelenleg: irányítatlan, súlyozott gráf Cél: az 1. csúcsból meghatározni a legrövidebb utat az 5. csúcshoz Dijkstra algoritmus: meghatározza valamely kezdőcsúcsból az összes többi csúcsba vezető legkisebb súlyú utat Mohó algoritmus szabo.zsolt@nik.uni-obuda.hu 49

Dijkstra algoritmus Tegyük fel, hogy a gráf tárolása és a lényeges műveletek már készen vannak Két tömböt használunk, mindegyik tömb ugyanannyi elemű, mint ahány csúcs van a gráfban Az int típusúelozocsucstömbben tároljuk a kiindulócsúcsból az egyes csúcsokhoz vezető legrövidebb útnál a csúcsot megelőző csúcs sorszámát A double típusúosszsulytömbben tároljuk a kiindulócsúcsból az egyes csúcsokhoz vezető jelenleg ismert legrövidebb út összsúlyát Az csúcsokat két halmazra kell osztani: függőben lévőcsúcsok és fix útvonalúcsúcsok. Mi ezt úgy oldjuk meg, hogy az i. csúcs még függőben van, ha OsszSuly[i]<0 Jelenlegi kezdőcsúcs: #1! szabo.zsolt@nik.uni-obuda.hu 50

Inicializálás Kell: kiindulócsúcs (Honnan), innen számoljuk a legrövidebb utat az összes többi csúcshoz Minden I csúcs távolsága legyen az I és a Honnan csúcs távolságának negatív értéke: OsszSuly tömb (a negatív távolság azt jelzi, hogy a csúcs még nincs kész) (a Honnan-nal nem szomszédos csúcsoknál ez double.negativeinfinity) Minden I csúcsra jelezzük, hogy a Honann I útvonalban az I csúcs előtti csúcs a Honnan (közvetlen él): ElozoCsucs tömb (ez a Honnan csúccsal szomszédos csúcsokra tényleg jó útvonalat definiál, a többi csúcsnál nincs olyan él, szóval ez biztos változni fog) A Honnan csúcs előtti csúcs legyen -1, ezzel jelezzük, hogy a Honnan a kiinduló-csúcs szabo.zsolt@nik.uni-obuda.hu 51

Kiinduló állapot IDX ElozoCsucs OsszSuly 1-1 0 2 1-10 3 1-4 1-5 5 1 - szabo.zsolt@nik.uni-obuda.hu 52

Algoritmus Ciklus, amíg van negatív súly (vagyis: amíg létezik nem-kész csúcs) 1. Minimum=az abszolút értékben legkisebb negatív súly sorszáma; 2. OsszSuly[minimum] = -OsszSuly[minimum]; 3. Minden nem-kész (vagyis negatív összsúlyú) csúcsra megnézzük, hogy a jelenlegi OsszSuly[i] súlynál abszolút értékben kisebb súlyt kapunk e, ha nem az ElozoCsucs[i] eddigi előzőcsúcson, hanem a Minimum-csúcson keresztül közelítjük meg. Ha igen, akkor ezzel frissítjük az OsszSuly[i]-t, és ElozoCsucs[i]=Minimum; Ciklus vége szabo.zsolt@nik.uni-obuda.hu 53

1. iteráció IDX ElozoCsucs OsszSuly 1-1 0 2 1 4-10 -8 3 1 4-4 1-5 5 1 4 - -14 5-16 A LEGKISEBB! (Abszolút értékben) szabo.zsolt@nik.uni-obuda.hu 54

2. iteráció IDX ElozoCsucs OsszSuly 1-1 0 2 4-8 3 4-14 2 4 1 5 5 4-16 8-9 A LEGKISEBB! (Abszolút értékben) szabo.zsolt@nik.uni-obuda.hu 55

3. iteráció IDX ElozoCsucs OsszSuly 1-1 0 2 4 8 3 2-9 4 1 5 9 A LEGKISEBB! (Abszolút értékben) 5 4 3-16 -10 szabo.zsolt@nik.uni-obuda.hu 56

4. iteráció IDX ElozoCsucs OsszSuly 1-1 0 2 4 8 3 2 9 4 1 5 5 3-10 10 A LEGKISEBB! (Abszolút értékben) szabo.zsolt@nik.uni-obuda.hu 57

Végállapot IDX ElozoCsucs OsszSuly 1-1 0 2 4 8 3 2 9 4 1 5 5 3 10 Az útvonalak nem Bármelyik csúcs elérhető feltétlenül alkotnak fát a kezdőcsúcsból indulva vagy egyenest, ez egyedi szabo.zsolt@nik.uni-obuda.hu 58

Fejlesztés Gráf osztály: int FPontok; double[,] FSulyok; string[] FCimkek; public Graf(int n) public void UjCimke(int n, string cimke) public void UjEl(int n, int m, double suly) public int GetPont(string cimke) public double GetSuly(int n, int m) Dijkstra algoritmushoz szükséges eljárások: private bool MinKer(double[] d, out int min) Visszaadja, hogy talált e negatív súlyt, és ha talált, akkor ezek közül melyik az abszolút értékben a legkisebb public List<int> Utvonal(int honnan, int hova) Itt először legeneráljuk az ElozoCsucs + OsszSuly tömböket, aztán iterálunk, majd legeneráljuk a specifikus utat szabo.zsolt@nik.uni-obuda.hu 59

Tesztelés (Ctrl+C, Ctrl+V) Graf g; g = new Graf(5); g.ujcimke(0, "#1"); g.ujcimke(1, "#2"); g.ujcimke(2, "#3"); g.ujcimke(3, "#4"); g.ujcimke(4, "#5"); g.ujel(0, 1, 10); g.ujel(0, 3, 5); g.ujel(1, 3, 3); g.ujel(1, 2, 1); g.ujel(2, 3, 9); g.ujel(3, 4, 11); g.ujel(2, 4, 1); utvonal(g, g.getpont("#1"), g.getpont("#5")); szabo.zsolt@nik.uni-obuda.hu 60

Tesztelés2 (Ctrl+C, Ctrl+V) g = new Graf(20); g.ujcimke(0, "Baja"); g.ujcimke(1, "Budapest"); g.ujcimke(2, "Debrecen"); g.ujcimke(3, "Eger"); g.ujcimke(4, "Esztergom"); g.ujcimke(5, "Győr"); g.ujcimke(6, "Gyula"); g.ujcimke(7, "Kaposvár"); g.ujcimke(8, "Kecskemét"); g.ujcimke(9, "Miskolc"); g.ujcimke(10, "Nyíregyháza"); g.ujcimke(11, "Pécs"); g.ujcimke(12, "Sopron"); g.ujcimke(13, "Szeged"); g.ujcimke(14, "Székesfehérvár"); g.ujcimke(15, "Szolnok"); g.ujcimke(16, "Szombathely"); g.ujcimke(17, "Tatabánya"); g.ujcimke(18, "Veszprém"); g.ujcimke(19, "Zalaegerszeg"); g.ujel(0, 1, 192.5); g.ujel(0, 6, 165.7); g.ujel(0, 13, 93.1); g.ujel(1, 2, 205.9); g.ujel(1, 3, 240.3); g.ujel(1, 8, 81.2); g.ujel(1, 11, 197.8); g.ujel(1, 18, 126.4); g.ujel(2, 3, 35.6); g.ujel(2, 6, 93.1); g.ujel(3, 6, 104.3); g.ujel(4, 7, 152.4); g.ujel(4, 16, 133.8); g.ujel(4, 17, 26.1); g.ujel(5, 12, 33.4); g.ujel(5, 16, 110.5); g.ujel(6, 15, 72.3); g.ujel(7, 11, 65.8); g.ujel(7, 14, 99.9); g.ujel(8, 9, 137.5); g.ujel(8, 13, 91.8); g.ujel(8, 15, 52.3); g.ujel(9, 1, 210.4); g.ujel(9, 6, 141.0); g.ujel(9, 10, 62.7); g.ujel(10, 2, 216.8); g.ujel(10, 15, 44.6); g.ujel(11, 0, 76.8); g.ujel(11, 5, 258.2); g.ujel(11, 14, 116.4); g.ujel(11, 19, 145.0); g.ujel(12, 14, 91.5); g.ujel(12, 17, 60.7); g.ujel(13, 1, 158.2); g.ujel(13, 15, 56.3); g.ujel(14, 1, 62.1); g.ujel(14, 5, 97.4); g.ujel(14, 17, 41.7); g.ujel(15, 1, 109.8); g.ujel(15, 3, 68.3); g.ujel(16, 17, 127.5); g.ujel(16, 19, 78.2); g.ujel(17, 18, 69.1); g.ujel(18, 11, 137.6); g.ujel(18, 14, 46.3); g.ujel(19, 1, 278.5); g.ujel(19, 4, 207.2); g.ujel(19, 6, 377.9); g.ujel(19, 12, 92.7); szabo.zsolt@nik.uni-obuda.hu 61 utvonal(g, g.getpont("szombathely"), g.getpont("szeged"));

Tesztelés szabo.zsolt@nik.uni-obuda.hu 62

Programozási Paradigmák Láncolt Lista Generikus osztályok Láncolt Lista megvalósítása Bináris keresőfa (BST) BST megvalósítása Gráfok Dijkstra algoritmus Kruskal algoritmus és Technikák szabo.zsolt@nik.uni-obuda.hu 63

Kruskal algoritmus Fa: körmentes (aciklikus), összefüggő gráf Feszítőfa: a gráf összes csúcsát tartalmazófa, amelynek élei a gráf éleinek részhalmazát alkotják, n csúcs esetén n-1 élből áll Minimális feszítőfa: a feszítőfák közül a legkisebb összsúlyú szabo.zsolt@nik.uni-obuda.hu 64

"Nem alakul ki kör"? Útvonalkereséssel (lassabb, talán könnyebben érthető) : Egy listába berakjuk az X csúcsból a feszítőfa meglévő élein keresztül elérhető összes csúcsot (tetszőleges bejárással: szélességi/mélységi). Ha a listában benne van az Y, akkor az X csúcsból a feszítőfa élein keresztül már elérhető az Y, vagyis X és Y egy komponensben van nem adható hozzá a feszítőfához az XY él, mert az kört hozna létre Komponensek használatával (ezt fogjuk implementálni) : Minden csúcshoz komponens-azonosítót rendelünk. Az él nem hoz létre kört, ha külön komponensben lévő csúcsokat köt össze: X és Y csúcs összeköthető éllel, ha a komponens-azonosítójuk különböző. Ezután minden csúcshoz azonos komponens-azonosítót kell rendelni, ami az X vagy az Y csúcs komponensében volt. szabo.zsolt@nik.uni-obuda.hu 65

Kruskal algoritmus példa szabo.zsolt@nik.uni-obuda.hu 66

Kruskal algoritmus példa szabo.zsolt@nik.uni-obuda.hu 67

Kruskal algoritmus példa szabo.zsolt@nik.uni-obuda.hu 68

Kruskal algoritmus példa szabo.zsolt@nik.uni-obuda.hu 69

Kruskal algoritmus példa szabo.zsolt@nik.uni-obuda.hu 70

Kruskal algoritmus példa szabo.zsolt@nik.uni-obuda.hu 71

Kruskal algoritmus példa szabo.zsolt@nik.uni-obuda.hu 72

Kruskal algoritmus példa szabo.zsolt@nik.uni-obuda.hu 73

Kruskal algoritmus megoldási elv 1. Definiáljuk a komponensektömböt, ahol komponensek[i] az i. csúcs komponens-azonosítóját jelzi. Kezdetben minden tömbelem egyedi [0..X] nincs él a feszítőfában 2. double FSulyok[,] List<GrafEl> Elek (GrafEl = {kezdőpont, végpont, súly}) 3. GrafEl rendezése súly szerint növekvő sorrendbe 4. Ciklus, amíg nincs kész a feszítőfa és nem fogynak el az élek a) Akt = sorrendben a következőél, ahol a kezdőpont és a végpont különböző komponensben van b) Ha van ilyen él, akkor az él hozzáadása a feszítőfához c) Ha van ilyen él, akkor az él kezdőpontjának és végpontjának a komponenseit egyesíteni kell 5. public List<GrafEl> Kruskal() szabo.zsolt@nik.uni-obuda.hu 74

Tesztelés (Ctrl+C, Ctrl+V) g = new Graf(8); g.ujcimke(0, "#1"); g.ujcimke(1, "#2"); g.ujcimke(2, "#3"); g.ujcimke(3, "#4"); g.ujcimke(4, "#5"); g.ujcimke(5, "#6"); g.ujcimke(6, "#7"); g.ujcimke(7, "#8"); g.ujel(g.getpont("#1"), g.getpont("#2"), 1); g.ujel(g.getpont("#1"), g.getpont("#6"), 3); g.ujel(g.getpont("#2"), g.getpont("#6"), 4); g.ujel(g.getpont("#2"), g.getpont("#3"), 2); g.ujel(g.getpont("#2"), g.getpont("#7"), 5); g.ujel(g.getpont("#6"), g.getpont("#7"), 8); g.ujel(g.getpont("#3"), g.getpont("#7"), 6); g.ujel(g.getpont("#3"), g.getpont("#4"), 4); g.ujel(g.getpont("#4"), g.getpont("#7"), 7); g.ujel(g.getpont("#7"), g.getpont("#8"), 1); g.ujel(g.getpont("#4"), g.getpont("#8"), 6); g.ujel(g.getpont("#4"), g.getpont("#5"), 7); g.ujel(g.getpont("#5"), g.getpont("#8"), 8); kruskal(g); szabo.zsolt@nik.uni-obuda.hu 75

Tesztelés szabo.zsolt@nik.uni-obuda.hu 76

Programozási Paradigmák Láncolt Lista Generikus osztályok Láncolt Lista megvalósítása Bináris keresőfa (BST) BST megvalósítása Gráfok Dijkstra algoritmus Kruskal algoritmus és Technikák szabo.zsolt@nik.uni-obuda.hu 77

Képek forrásai http://people.ksp.sk/~kuko/bak/ (megjegyzés: a fenti oldal nagyon jó, de kicsit más a BST, mint az előadáson ismertetett: törlés-c esetnél (amikor mindkét gyermekeleme létezik a törlendőelemnek) nem a bal oldali részfa legjobboldalibb elemét, hanem a jobb oldali részfa legbaloldalibb elemét használja) http://en.wikipedia.org/wiki/linked_list http://en.wikipedia.org/wiki/dijkstra's_algorithm http://en.wikipedia.org/wiki/kruskal's_algorithm http://people.inf.elte.hu/fekete/docs_2/grafalg/grafalg.htm http://www-b2.is.tokushima-u.ac.jp/~ikeda/suuri/kruskal/kruskal.shtml http://students.ceid.upatras.gr/~papagel/project/pseukrus.htm http://www.cs.usask.ca/classes/371/projects/99group8/tutorial/advanced/prim/prim_kruskal.ht ml szabo.zsolt@nik.uni-obuda.hu 80