190 lines
11 KiB
Plaintext
190 lines
11 KiB
Plaintext
Adatstruktúrák és algoritmusok
|
|
|
|
A problémamegoldás menete
|
|
Való problémák => absztrakt modellezés => algoritmus => program
|
|
|
|
Algoritmus
|
|
Az algoritmus egy hatékony eljárás egy feladat vagy probléma megoldására, melynek helyessége bizonyítható.
|
|
|
|
Hatékonyság
|
|
A hatékonyságot a futási idő és a memóriaigény határozza meg.
|
|
|
|
|
|
Algoritmusok futásidő elemzése
|
|
Futási idő: Egy bizonyos bemenetre a végrehajtott (gépfüggetlen) alapműveletek, vagy lépések száma.
|
|
|
|
A lépésszám pontos meghatározása helyett általában elegendő a lépésszám nagyságrendjének meghatározása,
|
|
és ebből már (kis óvatossággal) következtetni lehet arra,
|
|
hogy az algoritmus mennyire hatékony, avagy hogyan fog viselkedni nagyobb értékekre.
|
|
|
|
Aszimptotikus Hatékonyság
|
|
Ha a bemenet mérete elég nagy, akkor az algoritmus futási idejének csak a nagyságrendje érdekes
|
|
|
|
Az O ordó jelölés
|
|
Az O jelölést arra használjuk, hogy a futási idő növekedését aszimptotikusan alulról és felülről konstans távolságra behatároljuk.
|
|
|
|
Például a bináris keresés futási ideje legrosszabb esetben O(log n), helytelen lenne azt állítani, hogy a bináris keresés futási ideje O (log n) minden esetben.
|
|
A bináris keresés futási ideje soha nem rosszabb, mint O (log n), de van amikor ennél jobb.
|
|
|
|
Jó lenne egy olyan aszimptotikus jelölés ami azt fejezné ki, hogy "a futási idő maximum ennyivel nő, de ennél lassabban is nőhet." Erre használjuk az O jelölést.
|
|
|
|
Ha a futási idő O(f(n)), akkor elég nagy n esetén a futási idő maximum k*f(n) valamilyen konstans k érték mellett.
|
|
|
|
Azt mondjuk "f(n) ordója" vagy egyszerűen "O(f(n))" (kiejtésben használatos még az "ordó f(n)" is).
|
|
Az O jelölést aszimptotikus felső korlátként használjuk, mivel a futási időt felülről korlátozza, ha az input mérete elég nagy.
|
|
|
|
Bináris keresés futási ideje: O(log<sup>2</sup>n)
|
|
|
|
|
|
|
|
Tömb
|
|
A tömb egy olyan adatszerkezet, amely menet közben nem méretezhető át.
|
|
Tehát ha új elemeket szeretnénk egy meglévő tömbhöz adni, az csak úgy fog működni,
|
|
hogy létrehozunk egy új tömböt, ami az új elemek és a meglévő elemek tárolására alkalmas,
|
|
ezután pedig bemásoljuk a meglévő elemeket és az új elemeket a teljesen új tömbünkbe.
|
|
|
|
Tömbökben referencia típusokat is alkalmazhatunk,
|
|
viszont ebben az esetben nem elég példányosítani a tömböt,
|
|
az egyes elemeket is példányosítani kell, mivel ebben az esetben a tömb csak az objektumra mutató referenciát tárolja,
|
|
így a példányosítás nélkül a tömb elemeinek értéke null lesz.
|
|
|
|
Az osztályokat nem muszáj a konstrukroruk segítségével példányosítani.
|
|
Erre a célra vezették be a nyelvben az Object Initializer szintaxist,
|
|
amivel egy osztály adattagjai úgy adhatóak meg, mint egy tömb elemei.
|
|
|
|
Ez akkor jön jól, ha van egy osztályunk, amely adattagokkal rendelkezik,
|
|
de a konstruktor az objektum minden adattagjának beállításához nagyon összetett és komplikált lenne.
|
|
Ebben az esetben nem érdemes konstruktort írni. Az objektum inicializáló szintaxis a következő:
|
|
|
|
var objektum = new osztály(){
|
|
Adattag = érték,
|
|
Adattag2 = érték,
|
|
Adattag3 = érték
|
|
};
|
|
|
|
Ez a szintaxis csak olyan adattagok esetén alkalmazható, amelyek publikusan is írhatóak.
|
|
Egyéb védelmi szinttel rendelkező adattagok nem írhatóak ezzel a módszerrel.
|
|
Ezen adattagok beállítására továbbra is a konstruktor szintaxis használható.
|
|
|
|
Az osztályokat
|
|
|
|
Tömbök kezelését segítő metódusok
|
|
|
|
Length{ get;}
|
|
|
|
long Length{get;}
|
|
Visszaadja az aktuális tömb elemeinek a számát hosszú egész típusban.
|
|
Akkor jön jól, ha nagyon nagy méretű tömböket szeretnénk kezelni.
|
|
|
|
int Rank{get;}
|
|
Visszaadja a tömb dimenzióinak a számát
|
|
|
|
Ezen tulajdonságokon kívül az Array osztály számos statikus metódust tartalmaz,
|
|
amelyeket felhasználhatunk tömbök kezelésére.
|
|
Ezek közül a leghasznosabbak és legfontosabbak:
|
|
Array.Clear(Array array, int index,int length);
|
|
|
|
Array.Copy(Array sourceArray, Array destinationArray, int length);
|
|
Array.Copy(Array sourceArray, Array destinationArray, long length);
|
|
//harmadik paraméter a másolandó elemek száma
|
|
|
|
Array.Copy(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length);
|
|
|
|
int Array.IndexOf(Array array, object value);
|
|
int Array.IndexOf(Array array, object value, int startIndex);
|
|
|
|
int Array.LastIndexOf(Array array, object value);
|
|
int Array.LastIndexOf(Array array, object value, int startIndex);
|
|
|
|
Array.Reverse(Array array);
|
|
Array.Reverse(Array array, int index, int length);
|
|
// második elem a kezdőelem indexét adja meg, a harmadik az elemk számát adja meg
|
|
|
|
Array.Sort(Array array);
|
|
//Akkor ha az IComperable<T> implem,entálva van
|
|
|
|
Array.Sort(Array keys, Array items);
|
|
//Két tömb elemeinek a sorbarendezése, méghozzá úgy,hogy az első paraméterként megadott tömb kulcsokat tartalmaz,
|
|
//amelyhez a második paraméterként megadott tömb értékek társulnak.
|
|
|
|
Adatstruktúra interfészek
|
|
A kollekciókhoz kapcsolódó interfészek közül az egyik legfontosabb az IEnumerable<T> interfész.
|
|
Ez teszi lehetővé, hpgy mindegyik kollekción implementáéciótól függetlenül végig tudjuk uteráléni egy foreach ciklussal.
|
|
|
|
Az absztrakció következő szintje az IReadOnlyCollection és a ICollection interfészek.
|
|
Az ICollection<T> egy módosítható kollekciót ír le aminek at elemei törölhetőek és bővíthetőek.
|
|
A IReadOnlyCollection<T> pedig egy olyat,amiből csak olvasni tudunk, de tudjuk az elemek számát.
|
|
|
|
Az olyan típusok esetén, mint a lista halmaz és ... meg van valósítva mind a kettő.
|
|
|
|
Láncolt lista
|
|
A tömb adatszerkezet kiváló, ha előre tudjuk, hogy menni elemre van szükségünk.
|
|
A bővítés csak úgy lehetséges,ha létrehozunk egy újabb tömböt, aminek a mérete a hozzáadandó elemek számával meg van növelve.
|
|
Az új tömbbe átmásoljuk a meglévő elemeit, majd az új tömbhöz hozzáadjuk az új elemeket.
|
|
Végezetül pedig töröljük az eredeti tömböt.
|
|
|
|
Az algoritmus leírásából kiolvasható, hogy et nem éppen ideális,mivel a sebességre igen negatív hatással van a másolás.
|
|
Továbbá a másolás folyamán egy rövid időre duplázódik a programunk memóriahasználata.
|
|
|
|
Egy sokkal jobb megoldása lehet nagy mennyiségű előre nem ismert számú adat tárolására a láncolt lista szerkezet.
|
|
|
|
A láncolt lista egy eleme két részből épül fel. Egyrészt tartalmazza a tárolni kívánt adaott,
|
|
vagy adatokat és tartalmaz egy olyan mutatót, ami a lista eg másik elemét mutatja.
|
|
Ha a referencia a következő elemre nem létezik, akkor a lánc végén vagyunk.
|
|
|
|
A láncolt lista a dinamikus tömbhöz képest hátránya a közbülső elemnek elérhatőségéből ered.
|
|
Míg egy tömb esetén ha tudjuk,hogy a k. elemet szeretnénk elérnim akkor a tömb indexelésével rögtön hozzáférhefünk ehhet az adathoz, addog a láncolt listában a lista elejéről indulva a mutatókon keresztül addig kell lépkedni, míg a k. elemhez nem értünk.
|
|
A véletlenszerű lista elem megtalálása a lista hosszával arányos időt igényel.
|
|
|
|
Egyszeresen láncolt lista
|
|
Egyszeresen láncolt listában egy darab mutató jelöli a lista rákövetkező elemét.
|
|
Ha ismerjük a lista legelső elemét (lista feje), akkor abból elindulva a mutatók segítségével végig járhatjuk a listában tárolt elemeket.
|
|
A lista legutolsó elemének mutatójának értéke null, ez jelzi, hohgy tovább nem tudunk haladni a listában.
|
|
Láncolt lista esetén általában egyszeresen láncolt listára gondolunk.
|
|
|
|
Csomopont osztály: az adatot és a következő elemre mutató referenciát tartalmazza.
|
|
LancoltLista osztály: tartalmazza a listához szükséges főbb műveletekez:
|
|
Hozzaad: új elemet ad a lista végéhez
|
|
Torol: töröl
|
|
Kiir: kiír
|
|
|
|
Pogram osztály:
|
|
Teszteli a fenit műveleteket, létrehozza a listát, hozzáad elemeket,
|
|
töröl egy létező és egy nem létező elemet, majd kiírja a lista tartalmát.
|
|
|
|
Kétszeresen láncolt lista
|
|
Kétszeresen láncolt lsuita esetán 2db hivatkozűs van egy csomópontban,
|
|
az egyik az előző a másik a következő csomópontra mutat, C# ban kétszeresen láncolt listák vannak.
|
|
Hasonlóan mint a listák, szintén osztályból vannak létrehozva és ezért referencia típus,
|
|
természetesen referencia másolás történik értékadásnál.
|
|
|
|
Mint a listák esetében is a LinkedList beírása utám a <> jelek közé kerül a láncolt listánk típusa és a megszokott név,
|
|
egyenlőségjel a new operátor valamint újra a LinkedList és el ne felejtsük a zárójeleket!
|
|
|
|
LinkedList<string> lancoltlista = new LinkedList<string>();
|
|
|
|
Ezután a Linkedlist.AddLast(érték) metódussal tudunk a listánk végére beszúrni egy elemet,
|
|
vagy például az AddFirst(érték) metódussal pedig a lista első helyére.
|
|
|
|
Láncolt listák fontos metódusai
|
|
LinkedList.RemoveLast/First törli a lista utolsó vagy első elemét.
|
|
|
|
LinkedListNode<T> = LinkedList.Last/First
|
|
Visszaadja egy adott listában szereplő első vagy utolsó csomópontot, amelyben megtalálhatjuk a következő csinópontra mutató hivatkozást.
|
|
|
|
A LinkedList<T> objektumban minden csomópont LinkedListNode<T> típusú.
|
|
Mivel a LinkedList<T> kétszeresen kapcsolódik, minden csomópont előre mutat a köevtkező csomópontra, illetve hátra az előzőre.
|
|
|
|
LinkedList.AddAfter(LinkedListNode, value) / AddBefore
|
|
Egy csomópont elé vagy után szúr be adatot.
|
|
|
|
LinkedListNode<T> = LinkedList.Find(keresett_ertek)
|
|
Visszaadja a megadott értékhez tartozó csomópontot.
|
|
|
|
Csomópontok - LinkedListNode
|
|
Egy listából létrehozunk egy-egy csomópontot, melyben az adott csomóponthoz tartozó érték és a következő csomópontra mutató hivatkozás van.
|
|
A következő csomópontra való ugráshoz a .Next metódust kell használnunk, hogy visszafele közlekedjünk pedig a .Previous metódust kell használnunk.
|
|
A .Value metódus az adott csomópontban eltárolt adatot adja vissza.
|
|
Mivel tudjuk, hogy a láncolt listák utolsó, illetve első eleme null értékű, így egy while ciklussal is végig tudunk menni az adott láncolt listán,
|
|
a léptetéséről a Next gondoskodik.
|