Adatbázis rendszerek 1. 1. Gy: Algoritmusok C-ben 53/1 B ITv: MAN 2015.09.08
Alapalgoritmusok Összegzés Megszámlálás Kiválasztás Kiválasztásos rendezés Összefésülés Szétválogatás Gyorsrendezés 53/2
Összegzés Feladat: Adott egy számhalmaz, határozzuk meg a számok összegét. 7 15 13 5 9 49 Megoldás: Egy változó értékét beállítjuk 0-ra (kinullázzuk) Ciklus segítségével végigmegyünk a sorozat elemein, és a kinullázott változóhoz rendre hozzáadjuk a sorozat aktuális elemét. Az eredmény az eredetileg kinullázott változó aktuális értéke. 53/3
Összegzés Pszeudokód: Be: N ciklus i= 1.. N ismétel Be: A[ i ] ciklus vége Összeg = 0 ciklus i= 1.. N ismétel Összeg = Összeg + A[ i ] ciklus vége Ki: Összeg 53/4
Összegzés Struktogram: Be: n i = 1.. n Be: A [ i ] s = 0 i = 1.. n s = s + A[ i ] Ki: s Tömb elemszámának beolvasása Tömbelemek beolvasása Összeg változó (s) kinullázása Összegzés Eredmény kiírása 53/5
Összegzés 1 START Be: n n: elemek száma s = 0 i = 0 s: összeg i = 0 i: ciklusváltozó i= i + 1 53/6 i= i + 1 Be: A[ i ] i < n 1 A: elemek tömbje s= s + A [ i ] i < n Ki: s STOP
Összegzés C kód #include <stdio.h> main() { int A[20]; int i, n; printf("\nelemek száma? (max 20!) = "); scanf("%d", &n); for (i=0; i<n; i++){ printf("\n Elem[%d] = ", i); scanf("%d", &A[i]); } int s=0; for (i=0; i<n; i++) s=s+a[i]; printf("\n Az elemek összege = %d", s); } 53/7
Alapalgoritmusok Összegzés Megszámlálás Kiválasztás Kiválasztásos rendezés Összefésülés Szétválogatás Gyorsrendezés 53/8
Megszámlálás Feladat: Adott egy számhalmaz, és egy feltétel. Határozzuk meg, hogy az adatok közül hány darab tesz eleget a feltételnek. Feltétel: a szám legyen kisebb 10-nél 7 15 13 5 9 3 Megoldás: Kinullázunk egy változót. Ciklus segítségével végigmegyünk a tömb elemein. Megvizsgáljuk őket, és ha a tömbelem a feltételnek megfelel, a kinullázott változóhoz hozzáadunk egyet. Az eredmény az eredetileg kinullázott változó aktuális értéke. 53/9
Megszámlálás Pszeudokód: Be: N ciklus i= 1.. N ismétel Be: A[ i ] ciklus vége S = 0 ciklus i=1.. N ismétel Ha A[ i ] < 10 akkor S = S+1; ciklus vége Ki: S 53/10 Struktogram: Be: n i = 1.. n Be: A [ i ] db = 0 i = 1.. n A[i] < 10 db=db+1 Ki: db
Megszámlálás START db: darabszám 1 db = 0 i = 0 Be: n i= i + 1 53/11 i = 0 i= i + 1 Be: A[ i ] i < n 1 A[i] < 10 db = db + 1 i < n Ki: db STOP
Megszámlálás C kód #include <stdio.h> main() { int A[20]; int i, n; printf("\nelemek száma? (max 20!) = "); scanf("%d", &n); for (i=0; i<n; i++){ printf("\n Elem[%d] = ", i); scanf("%d", &A[i]); } int db=0; for (i=0; i<n; i++) if (A[i] < 25) db=db+1; printf("\n A megfelelő (< 25) elemek száma = %d", db); } 53/12
Alapalgoritmusok Összegzés Megszámlálás Kiválasztás Kiválasztásos rendezés Összefésülés Szétválogatás Gyorsrendezés 53/13
Kiválasztás Feladat: Adott egy számhalmaz, és egy feltétel. Határozzuk meg, hogy melyik adat tesz eleget leginkább a feltételnek. Feltétel: a legkisebb szám 7 15 13 5 5 Megoldás: Egy változóba (MIN) berakjuk a tömb első elemének az értékét. Ezután a 2. elemtől kezdve egy ciklussal végignézzük a tömb elemeit, és ha a vizsgált elem kisebb a MINértékénél, akkor berakjuk az értékét a MIN-változóba, így a MIN-értéke az addig megvizsgált elemek közül mindig a legkisebbet tartalmazza. 53/14 Eredmény: a MIN változó értéke.
Kiválasztás Pszeudokód: Be: N ciklus i= 1.. N ismétel Be: A[i] ciklus vége MIN = A[1] ciklus i= 2.. N ismétel Ha A[i] < MIN akkor MIN = A[i]; ciklus vége Ki: MIN 53/15 Struktogram: Be: n i < n Be: A [ i ] m = A [1] i = 2.. n A[i] < m m=a [i] Ki: m
Kiválasztás START m: legkisebb elem 1 m=a [1] i = 1 Be: n i = 0 i= i + 1 i= i + 1 A[i] < m m = A [i] 53/16 Be: A[ i ] i < n 1 i < n Ki: m STOP
Kiválasztás C kód #include <stdio.h> main() { int A[20]; int i, n; printf("\nelemek száma? (max 20!) = "); scanf("%d", &n); for (i=0; i<n; i++){ printf("\n Elem[%d] = ", i); scanf("%d", &A[i]); } int min=a[0]; for (i=1; i<n; i++) if (A[i] < min) min=a[i]; printf("\n A megfelelő (legkisebb) elem = %d", min); } 53/17
Alapalgoritmusok Összegzés Megszámlálás Kiválasztás Kiválasztásos rendezés Összefésülés Szétválogatás Gyorsrendezés 53/18
Kiválasztásos rendezés Feladat: Adott egy számhalmaz, és valamilyen rendezési szempont (rendezési kulcs). Rendezzük sorba az adatokat. Szempont: növekvő sorrend 7 15 13 5 5 7 13 15 53/19
Kiválasztásos rendezés Feladat: Adott egy tömb, rendezzük az elemeit növekvő sorrendbe. Módszer: Keressük ki a legkisebb elemet, és tegyük azt a tömb első helyére. Lépjünk egy hellyel odébb (második elem), és keressük ki a maradék elemek közül a legkisebbet. Tegyük ezt a második helyre. Lépjünk eggyel odébb, 53/20
Kiválasztásos rendezés Megoldás: Visszavezetjük a rendezést a kiválasztásra Két egymásba ágyazott ciklust alkalmazunk. A külső (I-változójú) azt vezérli, hogy hányadik helyre keressük a megfelelő adatot. A belső (J-változójú) a maradék elemek közül választja ki a megfelelőt. Ha csere szükséges, akkor azt egy segédváltozó (C) bevezetésével valósítjuk meg 53/21
Csere segédváltozó használatával Kiindulás: A B C 8 3 1. lépés: 8 3 8 C = A 2. lépés: 3 3 8 A = B 3. lépés: 3 8 8 B = C Végeredmény: 3 8 8 53/22 B ITI T MAN
Kiválasztásos rendezés Kiindulás: 53/23 7 15 13 5 Külső ciklus: i melyik helyre keressük a legkisebb elemet Belső ciklus: j végigmegy az i-től magasabb indexű elemeken i=1, j=2 7 15 13 5 j=3 7 15 13 5 Nincs csere Nincs csere j=4 7 15 13 5 Csere i=2, j=3 5 15 13 7 Csere j=4 5 13 15 7 Csere i=3, j=4 5 7 15 13 Csere Végeredmény: 5 7 13 15
Kiválasztásos rendezés Pszeudokód: Be: N c1-ciklus i= 1.. N ismétel Be: A[i] c1-vége ck-ciklus i=1.. N-1 ismétel cb-ciklus j= i+1.. N ismétel ha A[j] < A[i] akkor C:=A[i], A[i]:= A[ j], A[ j]:=c feltétel vége cb-vége ck-vége c2-ciklus i= 1.. N ismétel Ki: A[i] c2-vége 53/24 Struktogram: Be: n i = 1.. n Be: A [ i ] m = A [1] i = 1.. n-1 j = i+1.. n c=a[i] A[i]=A[ j] A[ j]=c i = 1.. n A[ j]<a[i] Ki: A [i]
Rendezés START Be: n i = 0 i= i + 1 Be: A[ i ] i < n 53/25 1 1 i = 1 j = i + 1 c = A [i] A[i] = A[ j] A[ j] = c A[ j]<a[i] j < n i < n-1 2 j = j+1 i = i+1 c: segédváltozó 2 i = 0 i= i + 1 Ki: A[ i ] i < n STOP
Kiválasztásos rendezés C kód #include <stdio.h> main() { int A[20]; int i, n, j, c; printf("\nelemek száma? (max 20!) = "); scanf("%d", &n); for (i=0; i<n; i++){ printf("\n Elem[%d] = ", i); scanf("%d", &A[i]); } for (i=0; i<n-1; i++) for (j=i+1; j<n; j++) if (A[j] < A[i]) {c = A[i]; A[i]= A[j]; A[j]= c;} for (i=0; i<n; i++) printf("%d. elem \t %d \t \n", i, A[i]); 53/26 }
Alapalgoritmusok Összegzés Megszámlálás Kiválasztás Kiválasztásos rendezés Összefésülés Szétválogatás Gyorsrendezés 53/27
Összefésülés Feladat: Adott két vagy több rendezett számhalmaz. Egyesítsük úgy az adatokat, hogy az eredmény halmaza is rendezett legyen. 5 10 13 7 15 20 5 7 10 13 15 20 53/28
Összefésülés Két tömb elemeinek összefésülése növekvő sorrendben: 1-re beállítjuk két segédváltozó értékét, ezek jelzik, hogy a két kiinduló tömb hányadik elemét vizsgáljuk meg. Indítunk egy ciklust, melynek lépésszáma a két tömb elemszámának az összege, így tudunk majd mindkét kiinduló tömb elemein végigmenni. A ciklusban megállapítjuk, hogy a segédváltozók által jelzett tömbelemek közül melyik a kisebb, és ezt az elemet áttesszük az eredmény tömbbe, és amelyik kiinduló tömbből áttettük az elemet, annak a segédváltozóját megnöveljük 1-el. Eredmény az eredmény tömb. 53/29
Összefésülés Pszeudokód: Be: N ciklus i= 1.. N ismétel Be: A[i] ciklus vége Be: M ciklus i= 1.. M ismétel Be: B[i] ciklus vége 53/30 j= 1, k= 1 ciklus i= 1.. N+M ismétel ha A[ j] < B[k] akkor C[i] = A[ j] j= j+1 különben C[i] = B[k] k= k+1 feltétel vége ciklus vége ciklus i= 1.. N+M ismétel Ki: C[i] ciklus vége
Összefésülés 2 START 1 i = 0 j = 1 k = 1 Be: n Be: m i = 0 i = 0 i = i + 1 i= i + 1 Be: A[ i ] i= i + 1 Be: B[ i ] C[i]=A[ j] j = j+1 A[ j]<b[k] C[i]=B[k] k = k+1 53/31 i < n 1 i < m 2 i < n+m 3
Összefésülés 53/32 3 i = 0 i= i + 1 Ki: C[ i ] i < n+m STOP Be: n i = 1.. n Be: A [ i ] j = 1, k = 1 i = 1.. n+m A[ j]<b[k] Be: m i = 1.. m C[i]=A[ j] j = j+1 Be: B [ i ] i = 1.. n+m Ki: C[ i ] C[i]=B[k] k = k+1
Alapalgoritmusok Összegzés Megszámlálás Kiválasztás Kiválasztásos rendezés Összefésülés Szétválogatás Gyorsrendezés 53/33
Szétválogatás Feladat: Adott egy számhalmaz, és egy (vagy több) feltétel. Válogassuk szét az adatokat a feltételnek megfelelően több halmazba. 5 7 10 14 15 20 Feltétel: páros és páratlan számok 10 14 20 5 7 15 53/34
Szétválogatás Páros vagy páratlan számok: 1-re beállítjuk két segédváltozó értékét, ezek jelzik, hogy a két eredmény tömb (páros, páratlan) hányadik helyére kerül a kiinduló tömb aktuálisan vizsgált eleme. Ciklus segítségével végigmegyünk a kiinduló tömbön. Ha az aktuális elem 2-vel elosztva 0 maradékot ad (páros), akkor a páros tömbbe, a segédváltozója által jelzett helyre rakjuk, és a segédváltozót növeljük 1-el. Ha a maradék 1, akkor a vizsgált elem a páratlan tömbbe kerül, és ennek segédváltozóját növeljük meg. Eredmény a két eredmény tömb. 53/35
Szétválogatás Be: N Pszeudokód: ciklus i= 1.. N ismétel Be: A[i] ciklus vége j= 1, k= 1 ciklus i= 1.. N ismétel ha A[i] mod 2 = 0 akkor B[ j] = A[i] j= j+1 különben C[k] = A[i] k= k+1 feltétel vége ciklus vége 53/36 ciklus i= 1.. j-1 ismétel Ki: B[i] ciklus vége ciklus i= 1.. k-1 ismétel Ki: C[i] ciklus vége
Szétválogatás START Be: n 1 i = 0 j = 1 k = 1 2 i = 0 i = 0 i= i + 1 Be: A[ i ] i < n 53/37 1 B[ j]=a[ i] j = j+1 i = i + 1 A[i] mod 2=0 i < n 2 C[k]=A[ i] k = k+1 i= i + 1 Ki: B[ i ] i < j-1 3
Szétválogatás 53/38 3 i = 0 i= i + 1 Ki: C[ i ] i < k-1 STOP Be: n i = 1.. n Be: A [ i ] j = 1, k = 1 i = 1.. n A[i] mod 2=0 B[ j]=a[i] j = j+1 i = 1.. j-1 Ki: B[ i ] i = 1.. k-1 Ki: C[ i ] C[k]=A[i] k = k+1
Alapalgoritmusok Összegzés Megszámlálás Kiválasztás Kiválasztásos rendezés Összefésülés Szétválogatás Gyorsrendezés 53/39
Gyorsrendezés Feladat: adott egy tömb, rendezzük sorba az elemeit. 1. Válasszuk ki a tömb középső elemét. Ötlet: használjuk ehelyett az első és az utolsó elem átlagát. 2. Rendezzük úgy át az elemeket, hogy a középsőnél kisebb elemek a tömb elejére, a tőle nagyobbak a tömb végére kerüljenek. 3. Vegyük a középsőnél kisebb elemek résztömbjét, meg a középsőnél nagyobb elemek résztömbjét, és ismételjük meg a lépéseket (1-2-3). Akkor végzünk, ha a résztömbökben max. egy eleme marad. 53/40
Gyorsrendezés Pl.: 3 9 1 7 5 2 4 6 8 Középső: (3+8)/2=5 3 2 1 4 5 9 7 6 8 Alsó blokk középsője: (3+5)/2=4 Felső blokk középsője: (9+8)/2=8 3 2 1 4 5 7 6 8 9 Alsó blokk középsője: (3+1)/2=2 Felső blokk középsője: (6+7)/2=6 1 2 3 4 5 6 7 8 9 53/41
Gyorsrendezés Módszer: az első kettéválasztás és átrendezés után a két résztömbre meghívjuk ismét a gyorsrendezést, vagyis saját magát hívja a függvény. Ezt rekurziónak nevezzük. 53/42
Gyorsrendezés C kód void qs(double * t, int meret){ if (meret<2) return; // ha 1 vagy 0 tömbelem van, kész int left=0, right=meret-1; // a két szélén kezdjük double med=(t[right]+t[left])/2; // a középső elem kiválasztása do { while (t[left]<med)left++; // átlépjük a középsőnél kisebb elemeket while (t[right]>med)right--; // átlépjük a középsőnél nagyobb elemeket if (right >= left){ // Ha nem ment el egymás mellett a kép "pointer", felcseréljük az elemeket double temp=t[left]; t[left]=t[right]; t[right]=temp; left++; right--; } } while (right>=left); // Ha elment egymás mellett a két "pointer", kész a szétválogatás qs(t,right+1); // Az alsó résztömbre meghívjuk a quicksortot qs(t+left,meret-left); // A felső résztömbre meghívjuk a quicksortot } 53/43
File-kezelés C-ben Tömb kiírása szövegfájlba Beolvasás szövegfájlból 53/44
Tömb kiírása fájlba C kód (1) #include <stdio.h> main() { int A[20]; int i, n; FILE *fp; void fkiir(){ fp=fopen("adat.txt","wt"); for (i=0; i<n; i++) fprintf(fp,"%d\n",a[i]); fflush(fp); fclose(fp); } 53/45
Tömb kiírása fájlba C kód (2) printf("\nelemek száma? (max 20!) = "); scanf("%d", &n); for (i=0; i<n; i++){ printf("\n Elem[%d] = ", i); scanf("%d", &A[i]); } fkiir(); } 53/46
File-kezelés C-ben Tömb kiírása szövegfájlba Beolvasás szövegfájlból 53/47
Beolvasás szövegfájlból C kód (1) #include <stdio.h> main() { int A[20]; int i, n; FILE *fp; void folvas(){ fp=fopen("adat.txt","rt"); i=-1; while (!feof(fp)){ i++; fscanf(fp,"%d",&a[i]); } fclose(fp); n=i+1; } 53/48
Beolvasás szövegfájlból C kód (2) folvas(); printf("\nelemek száma= %d\n", n); for (i=0; i<n; i++) printf("%d. elem \t %d \t \n", i, A[i]); } 53/49
Feladatok Fájlban adott kb. 20 darab szám, gyorsrendezéssel rendezze a fájl tartalmát. Olvassa be az adatokat egy tömbbe. Rendezze a tömböt. Írja vissza az adatokat a fájlba. Próbálja tömb használata nélkül megoldani a feladatot. 53/50
53/51
Felhasznált irodalom Knuth, D.E: A számítógép-programozás művészete 1-3, Műszaki Könyvkiadó, Budapest, 1987-88. Brian W. Kernighan Dennis M. Ritchie: A C programozási nyelv, Műszaki Könyvkiadó, 1988 Wirth, N: Algoritmusok + Adatstruktúrák = Programok, Műszaki Könyvkiadó, Budapest, 1982 Benkő László Benkő Tiborné Tóth Bertalan: Programozzunk C nyelven, Computerbooks, 2008 Elek Tibor: A C programozási nyelv, elektronikus jegyzet Ficsor Lajos: Bevezetés a C programozási nyelvbe, elektronikus jegyzet 53/52
VÉGE VÉGE 53/53