139 lines
7.4 KiB
Plaintext
139 lines
7.4 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.
|
|
|