Tömbök és programozási tételek C# nyelven
Tömb fogalma és tulajdonságai több, azonos típusú változó (érték) együttes kezelésére referencia típusú változó nem konkrét érték kerül bele, hanem memóriacím típusa és mérete nem módosítható a deklarálás után elemei a tömbön belül sorszámozottak (index) a sorszámozás 0-val kezdődik! egy eleméhez a neve utáni szögletes zárójelbe megadott sorszámmal (index) férhetünk hozzá
Tömbök fajtái Egydimenziós (sorozat, vektor) Kétdimenziós (mátrix, azaz sora és oszlopa is van) Többdimenziós (3-tól) deklarálásnál meg kell adni, hány dimenziós legyen a tömb
Műveletek tömbökkel (egydimenziós) Deklarálás: int[] tombnev; Tömb létrehozása Þ elemszám megadása + helyfoglalás a memóriában tombnev=new int[10]; egy 10 elemű tömb létrehozása a deklaráció és a létrehozás összevonható: int[] tombnev=new int[10];
Deklaráció és értékadás kétdimenziós tömbnél a deklaráció: int[,] tomb2 = new int[4,3]; 4 soros és 3 oszlopos tömb értékadás 2 egymásba ágyazott ciklussal Érték elhelyezése tömbben: egy elem esetében: tombnev[5] = 25; több elem esetében: int[] tombnev = {1, 2, 3, 4, 5, 6}; számlálós ciklussal
Tömbelem elérése (indexelés) tombnev[index] az index csak nemnegatív egész szám lehet az első elem indexe: 0 az utolsó elem indexe: elemszám-1 kisebb vagy nagyobb index megadása futási hibát okoz tombnev 28 3 17 11 50 tombev=new int[5]; 0. 1. 2. 3. 4. tombnev[3]
Tömb hossza Tömb hossza = tömbben elhelyezhető elemek száma, azaz a tömb mérete A tömb hossza lekérdezhető: tombnev.Length Többdimenziós tömbnél: tomb2.GetLength(0), tomb2.GetLength(1)... (ahány dimenzió van-1)
Tömb feltöltése értékadással Számlálós ciklussal: for (int i = 0; i < tombnev.Length; i++) { tombnev[i]=kifejezés; } véletlen számokkal való feltöltéshez
Tömb feltöltése felhasználói bevitellel Számlálós ciklussal: for(int i=0;i<tombnev.Length;i++) { Console.Write("Adja meg a {0}. tömbelemet: ",i); tombnev[i]=int.Parse(Console.ReadLine()) ; } A típuskonverziót a megfelelő típusra kell elvégezni (itt: egész szám)
Tömb kiíratása Foreach ciklussal: foreach (int ertek in tombnev) { Console.Write("{0} ", ertek); } A ciklusváltozó nem módosítható az utasításban (ha szükséges, akkor for ciklus kell) Addig megy a ciklus, amíg a tömb végére nem ér szóközzel elválasztva
Programozási tételek
Programozási tételek Típusalgoritmusok gyakran előforduló feladatokra Nem egyedi feladatokra, hanem feladat csoportokra ad megoldást (általános) Bemenő és kimenő adatok jellege szerint lehet: egy sorozathoz egy értéket rendelő egy sorozathoz egy sorozatot rendelő egy sorozathoz több sorozatot rendelő több sorozathoz egy sorozatot rendelő
Programozási tételek Egy sorozathoz egy értéket rendelő: összegzés tétele: tömbelemek összege megszámlálás tétele: hány darab T tulajdonságú elem van a tömbben kiválasztás tétele: hol van az első T tulajdonságú elem a tömbben előfeltétel: biztosan van T tulajdonságú elem a tömbben
Programozási tételek Egy sorozathoz egy értéket rendelő (folyt): eldöntés tétele: van-e T tulajdonságú elem a tömbben lineáris keresés tétele: van-e T tulajdonságú elem a tömbben, és ha igen, hol található az első (index) maximumkiválasztás tétele: legnagyobb tömbelem (helye = index) minimumkiválasztás tétele: legkisebb tömbelem (helye = index)
Programozási tételek Egy sorozathoz egy sorozatot rendelő: kiválogatás tétele: T tulajdonságú elemek kiválogatása egy másik tömbbe rendezések: tömbelemek sorba rendezése közvetlen kiválasztásos rendezés minimum kiválasztásos rendezés buborékrendezés beszúró rendezés
Összegzés tétele algoritmus összegzés int i, ossz=0; int[] x=new int[n]; … for(i=0;i<x.Length;i++) { ossz+=x[i]; } Console.WriteLine("Az összeg: {0}", ossz); algoritmus összegzés var i, össz: egész x: tömb [1..n] egész … össz:=0 ciklus i:=1..n lépésköz=1 ismétel össz:=össz + x[i] cvége ki: össz algoritmus vége
Összegzés tétele átlag számításához további két dolgot kell megadni: a változók közé fel kell venni az átlag nevű, valós típusú változót double atlag; a kiíratás előtt ki kell számolni az átlagot: atlag=ossz/x.Length;
Megszámlálás tétele { if(x[i] T tulajdonságú) db++; } algoritmus megszámlálás változó i, db : egész x : tömb [1..n] egész … db := 0 ciklus i:=1..n lépésköz=1 ismétel ha (x[i] T tulajdonságú) akkor db:= db+1 hvége cvége ki:db …. algoritmus vége int i, db=0; int[] x=new int[n]; … for(i=0;i<x.Length;i++) { if(x[i] T tulajdonságú) db++; } Console.WriteLine("A T tulajdonságú elemek száma: {0}", db);
Kiválogatás tétele { if(x[i] T tulajdonságú) x2[db]=x[i]; db++; } int i, db=0; int[] x=new int[n], x2=new int[n]; … for(i=0;i<x.Length;i++) { if(x[i] T tulajdonságú) x2[db]=x[i]; db++; } algoritmus kiválogat változó i, db :egész X, X2 : tömb [1..n] egész … db:=0 ciklus i=1-től n-ig lépésköz 1 ismétel Ha (X[i] T tulajdonságú) akkor db:=db+1 X2[db]:=X[i] hvége cvége algoritmus vége
Kiválasztás tétele algoritmus kiválasztás változó i: egész int i=0; int[] x=new int[n]; … while(x[i] NEM T tulajdonságú) { i++; } Console.WriteLine("Az első T tulajdonságú elemek helye a tömbben: {0}", i+1); algoritmus kiválasztás változó i: egész változó x:tömb[1..n] egész … i:=1 amíg (x[i] nem T tulajdonságú) ismétel i:=i+1 avége ki: i algoritmus vége
Kiválasztás tétele Előfeltétel: biztosan legyen a tömbben T tulajdonságú elem Az elöltesztelő ciklus feltételében a megadott T tulajdonság ellenkezőjét kell beírni Pl.: ha a tömbben az 1-eseket keressük, akkor a feltétel ennek ellenkezője (nem egyenlő) lesz: x[i]!=1 A kisebb ellenkezője: nagyobb és egyenlő A nagyobb ellenkezője: kisebb és egyenlő Az indexelés miatt (0-tól) a ciklusváltozó kezdőértéke változik (algoritmushoz képest)
Eldöntés tétele int i=0; int[] x=new int[n]; bool van; … while((i<tomb.Length) && (x[i] NEM T tulajdonságú)) { i++; } van=(i<tomb.Length); if(van==true){ Console.WriteLine("Létezik a keresett elem."); } else { Console.WriteLine("Nem létezik a keresett elem."); algoritmus eldöntés változó i: egész VAN: logikai x: tömb [1..n] : egész … i:=1 amíg (i<=n) ÉS (x[i] nem T tulajdonságú) ismétel i:=i+1 avége VAN:=(i <= n) ha VAN akkor ki: "Létezik a keresett elem " különben ki: "Nincs a keresett elem a tömbben" hvége algoritmus vége
Lineáris keresés tétele int i=0; int[] x=new int[n]; bool van; … while((i<tomb.Length) && (x[i] NEM T tulajdonságú)) { i++; } van=(i<tomb.Length); if(van==true){ Console.WriteLine("Létezik a keresett elem, helye: {0}.",i+1); } else { Console.WriteLine("Nem létezik a keresett elem."); algoritmus linker változó i: egész VAN: logikai x: tömb [1..n] : egész … i:=1 amíg (i<=n) ÉS (x[i] nem T tulajdonságú) ismétel i:=i+1 avége VAN:=(i <= n) ha VAN akkor ki: i különben ki: "Nincs a keresett elem a tömbben" hvége algoritmus vége
Lineáris keresés tétele Amennyiben nem az adott T tulajdonságú elem helyét, hanem az értékét akarjuk kiíratni, akkor az i+1 nevű változó helyett az x[i+1] tömbelem értékét kell kiíratni. Az elem helyénél ne felejtsük el, hogy a sorszámozás NEM 1-től, hanem 0-tól történik! ezért kell a +1 kiíratásnál
Minimumkiválasztás tétele int i, min=0; int[] x=new int[n]; … for(i=1;i<x.Length;i++) { if(x[min]>x[i]) min=i; } Console.WriteLine("A legkisebb elem helye: {0}, értéke {1}", min+1,x[min]); algoritmus minimum változó i, min:egész x: tömb [1..n] : egész … min := 1 ciklus i:=2..n lépésköz 1 ismétel ha x[min] > x[i] akkor min := i hvége cvége ki: min, x[min] algoritmus vége
Maximumkiválasztás tétele int i, max=0; int[] x=new int[n]; … for(i=1;i<x.Length;i++) { if(x[max]<x[i]) max=i; } Console.WriteLine("A legnagyobb elem helye: {0}, értéke {1}", max+1,x[max]); algoritmus maximum változó i, max:egész x: tömb [1..n] : egész … max := 1 ciklus i:=2..n lépésköz 1 ismétel ha x[max] < x[i] akkor max := i hvége cvége ki: max, x[max] algoritmus vége
Rendezések
Rendezések A tömbökben az elemek általában nem rendezve tárolódnak sorba rendezésükhöz többféle rendezési algoritmust fejlesztettek ki Rendezési algoritmusok közvetlen kiválasztás minimumkiválasztás buborékrendezés beszúró rendezés
Közvetlen kiválasztásos rendezés Alapgondolat: az első elemet összehasonlítjuk az összes többi mögötte lévővel, és ha van kisebb, akkor kicseréljük őket amint az első elem a helyére került, a 2. elemmel folytatjuk Hátránya: az egyik leglassabb rendezés sok a felesleges csere (növeli a végrehajtás idejét)
A rendezés tulajdonságai N elemű tömb esetén: Helyfoglalás (tárigény): N+1 Összehasonlítások száma: (független a tömb előrendezettségétől) N(N-1) 2 Mozgatások száma: 3* 2
A rendezés algoritmusa int[] x=new int[N]; int i,j; elemtípus csere; for(i=0;i<A.Length-1;i++) { for(j=i+1;j<A.Length;j++) if(x[i]>x[j]) csere=x[i]; x[i]=x[j]; x[j]=csere; } algoritmus rendezés változó I,J: egész változó Csere: Elemtípus ciklus I:=1..N-1 ismétel ciklus J:=I+1..N ismétel ha x[I]>x[J] akkor csere:=x[I] x[I]:=x[J] x[J]:=csere hvége cvége algoritmus vége
Az algoritmus működése Két különböző ciklust indítunk a külső a tömb első elemétől az utolsó előttiig megy (i) a belső a tömb i+1. elemétől (először a másodiktól) indul az utolsóig (j) Az első i. elemet összehasonlítja a belső ciklus az összes j. elemmel, és ahol kisebbet talál nála, ott kicseréli az elemeket amikor végignézte az összes elemet a belső ciklus, akkor a külsőben az i értéke eggyel nő, majd újra kezdődik az összehasonlítás
Minimumkiválasztásos rendezés Alapgondolat: megkeressük a legkisebb elemet, majd azt kicseréljük az elsővel ezek után megkeressük a következő legkisebbet, amit a 2. elemmel cserélünk ki Hátránya: szélsőséges esetben rosszabb a közvetlen rendezésnél mivel a külső ciklus mindenképpen cserél
A rendezés tulajdonságai N elemű tömb esetén: Helyfoglalás (tárigény): N+1 Összehasonlítások száma: (független a tömb előrendezettségétől) N(N-1) 2 Mozgatások száma: (függ a tömb előrendezettségétől) Legalább: 0 Legfeljebb: 3*(N-1) Cserék száma: Legfeljebb: N-1
A rendezés algoritmusa algoritmus minrendezés változó I,J,Min: egész változó Minérték: Elemtípus ciklus I:=1..N-1 ismétel Min:=I ciklus J:=I+1..N ismétel ha A[Min]>A[J] akkor Min:=J hvége cvége ha Min<>I akkor Minérték:=A[Min] A[Min]:=A[I] A[I]:=Minérték algoritmus vége int[] A=new int[N]; int i,j,min; elemtípus csere; for(i=0;i<A.Length-1;i++){ min=i; for(j=i+1;j<A.Length;j++){ if(A[min]>A[j]){ min=j; } if(min!=i){ csere=A[min]; A[min]=A[i]; A[i]=csere;
Buborékrendezés Alapgondolat: két szomszédos elemet összehasonlítunk ha nem megfelelő a sorrendjük, megcseréljük őket Hátránya: nem túl hatékony, ezért a gyakorlatban nem igazán használják ha a belső ciklus nem cserél, utána már feleslegesen folytatódik a cserélgetés
A buborékrendezés tulajdonságai N elemű tömb esetén: Helyfoglalás (tárigény): N+1 Összehasonlítások száma: (független a tömb előrendezettségétől) N(N-1) 2 Mozgatások száma: (függ a tömb előrendezettségétől) Legalább: 0 Legfeljebb: Cserék száma: N(N-1) 2 3* N(N-1) 2
A rendezés algoritmusa algoritmus bubirendezés változó I,J: egész változó Csere: Elemtípus ciklus I:=N..2 lépésköz -1 ismétel ciklus J:=1..I-1 ismétel ha A[J]>A[J+1] akkor Csere:=A[J] A[J]:=A[J+1] A[J+1]:=Csere hvége cvége algoritmus vége int[] A=new int[N]; int i,j; elemtípus csere; for(i=A.Length-1;i>=1;i--){ for(j=0;j<=i-1;j++){ if(A[j]>A[j+1]){ csere=A[j]; A[j]=A[j+1]; A[j+1]=csere; }
Beszúró rendezés Alapgondolat: megnézzük a soron következő elemet, és megkeressük a helyét a tőle balra lévő (már rendezett) tömbben „kártyás” rendezés Hátránya: előfeltételhez kötött Előfeltétel: a tömb egy részének rendezettnek kell lennie legalább az első elemnek
A beszúró rendezés tulajdonságai N elemű tömb esetén: Helyfoglalás (tárigény): N+1 Összehasonlítások száma: Legalább: N-1 Legfeljebb: Mozgatások száma: (részben rendezett tömbben) Legalább: 2*(N-1) 2*(N-1)+ N(N-1) 2 N(N-1) 2
A beszúró rendezés tulajdonságai A buborékrendezésnél gyorsabb, de a minimumkiválasztásnál lassabb kis tömb esetén ez a leggyorsabb nagy tömb esetén nem hatékony Az előfeltétel miatt teljesen rendezetlen tömb esetén először a legkisebb elemet az első helyre kell tenni, és csak UTÁNA alkalmazható
A rendezés algoritmusa algoritmus bubirendezés változó I,J: egész változó X: Elemtípus ciklus I:=2..N ismétel J:=I-1 X:=A[I] amíg (J>=1) és (X<A[J]) ismétel A[J+1]:=A[J] J:=J-1 avége A[J+1]:=X cvége algoritmus vége int[] A=new int[N]; int i,j; elemtípus csere; for(i=1;i<A.Length;i++){ j=i-1; csere=A[i]; while((j>=0)&&(csere<A[j])){ A[j+1]=A[j]; j=j-1; } A[j+1]=csere;
Rendezések összehasonlítása 50 elemű tömb esetében: Közvetlen kiválasztás Minimum-kiválasztás Buborék Beszúró Helyfoglalás: 51 Összehasonlí-tások száma: 1225 49-1225 Mozgatások száma: 3675 0-147 0-3675 98-1323 Cserék száma: 0-49 0-1225