Előadást letölteni
Az előadás letöltése folymat van. Kérjük, várjon
1
(Bináris) Kupac (heap) adattípus
Bináris fa, amelyben minden csomópont értéke nagyobb mindegyik leszármazottjáénál kupactulajdonság (alaptípus, típusinvariáns) Magasság: a csúcsból a levélig vezető leghosszabb út Kiegyenlített: csak az utolsó réteg lehet nem teljes Ábrázolás: vektorban, rétegenként Minden réteg mérete=korábbi rétegek+1. Minden réteg első elemindexe=2h 2 14 16 3 4 10 9 8 7 1 Szülő: i/2 Balfa: 2*i Jobbfa: 2*i + 1
2
Adattípus definíció Kupac: csak a rendezésekre koncentrál
Elsőbbségi sor: adatbeszúrás, törlés stb. Használatuk: az integer tömb csak az adatok „kulcsát” (a rendezés kulcsát) jelzik, ehhez a gyakorlatban még járulékos adatok is tartoznak Pl: operációs rendszerekben a párhuzamosan futó feladatok listájának kezelésére használják
3
Kupac helyreállító eljárás egy elemre
kupacol(int i) – Feltételezzük, hogy i-re (a csomópont és gyerekei között) nem teljesül a kupactulajdonság, de feljebb igen private void kupacol(int i) { int bal = balkupac(i); int jobb = jobbkupac(i); int legnagyobb; if (bal<=meret && tomb[bal]>tomb[i]) legnagyobb = bal; else legnagyobb = i; if (jobb<=meret && tomb[jobb]>tomb[legnagyobb]) legnagyobb = jobb; if (legnagyobb!=i) { int csere = tomb[i]; tomb[i] = tomb[legnagyobb]; tomb[legnagyobb] = csere; kupacol(legnagyobb); } } Ha megtalálta a helyét, akkor már nem mozgatjuk/ keresünk tovább lefelé. Jobbrekurzió. Hogyan lehetne ciklussá átalakítani?
4
Kupacolás működés közben
Hatékonyság: Θ(magasság) Θ(log(n)) Egyetlen elemet görget lefelé addig, amíg a saját helyét el nem éri 2 4 16 3 8 10 9 14 7 1 2 14 16 3 8 10 9 4 7 1 2 14 16 3 4 10 9 8 7 1
5
Kupacolás teljes fára Kupacolás: a rossz helyen levő elemeket lefelé görgeti, mindig a nagyobb gyerek felé Vagyis: levélelemekre nem lehet kupacolni Teljes fára: minden egyes elemére, a levelek feletti elemtől kezdve a gyökérig (bottom-up) public void epit() { for (int i=(meret-1)/2; i>0; i--) kupacol(i); }
6
Kupacépítés hatékonysága
Hatékonyság(1): O(n log n) ??? Hatékonyság(2): - kupacol futási ideje a csúcs magasságának lineáris függvénye O(h) Bármely h magasságú (levéltől számítva) csúcsok száma legfeljebb <= n/(2h+1) -- ha a fa teljes lenne, akkor „=„ „Épít” futásideje „h” szerint összegezve h=0Σlg(n) (n/2h+1) * O(h) = O(n*h=0Σlg(n) (h/2h)) 0Σ∞…= 0+1/2+2/4+3/8… = KONSTANS hatékonyság = O(n) a kupaccá alakítás lineáris idő alatt fut le
7
A kupacrendezés algoritmusa
(Növekvő sorrendbe rendezünk…) - a legnagyobb elem a gyökér, az legyen a legutolsó az utolsót és az elsőt cseréljük - eggyel rövidebb vektort kupacoljuk. (csak az új első elem sértheti a kupactulajdonságot) public void rendez() { epit(); for (int i=hossz-1; i>0; i--) { int csere = tomb[i]; tomb[i]=tomb[0]; tomb[0] = csere; hossz--; kupacol(0); } Hatékonysága: O(n logn)
8
Kupacrendezés (példa)
2 14 16 3 4 10 9 8 7 1 16,14,10,8,7,9,3,2,4,1 2 8 14 3 1 10 9 4 7 1,14,10,8,7,9,3,2,4|16 14,8,10,4,7,9,3,2,1|16 2 8 10 3 9 1 4 7 8 9 2 3 1 4 7 1,8,10,4,7,9,3,2|14,16 2,8,9,4,7,1,3|10,14,16 9,8,3,4,7,1,2|10,14,16 8,7,3,4,2,1|9,10,14,16 2,8,3,4,7,1|9,10,14,16 7 8 3 1 4 2 1,7,3,4,2|8,9,10,14,16 Stb. stb. stb….
9
Elsőbbségi sorok Maximális elem visszaadása:
public class elsobbSor extends kupac { public integer max() { return (tomb(0)); } Maximális elem kivétele és törlése: public integer kiveszMax() { int maxi = max(); tomb[0] = tomb[meret--]; kupacol(0); return(maxi);}
10
Elsőbbségi sorok (tovább)
Elem beszúrása: public void beszur(int x) { tomb[++meret]=x; int i=meret-1; while (i>0 && tomb[szulo(i)]<x) { tomb[i] = tomb[szulo(i)]; i = szulo(i); } tomb[i] = x; } 1. Utolsó (levél) elemként felvesszük 2. Buborékoltatjuk fel a gyökér felé, addig, amíg egy nála nagyobb szülő elemet nem találunk
11
Rendezések Időszükséglet (legrosszabb, átlagos)
Helyszükséglet (helyben rendező) Legelterjedtebb fajtái: Buborékrendezés: (O(n2)) Beszúró rendezés: (Θ(n2)) Összefésülő rendezés: (Θ(n*log(n))) Kupacrendezés: (O(n*log(n))) Gyorsrendezés: (Θ(n2)) - legrosszabb esetre, átlagosan csak Θ(n*log(n)) kicsi a konstans szorzó helyben rendez Virtuális memóriabeli környezetben is jól használható
12
Gyorsrendezés (Hoare, 1962)
Alapelve: (oszd meg és uralkodj) 1. felosztjuk az A[p..r]A1[p..q] és A2[q+1..r] szakaszokra úgy, hogy A1<=A2 (DE!! NINCSenek rendezve!!) 2. Az A1 és A2 résztömböket rendezzük 3. Nincs szükség összefésülésre Az algoritmus sarokpontja: az 1. felosztó lépés. Ennek megvalósítása többféle is lehet public void gyorsrendez(int also, int felso) { if (also<felso) { int kozep = feloszt(also,felso) gyorsrendez(also,kozep); gyorsrendez(kozep+1,felso); } }
13
Gyorsrendezés felosztó algoritmusa
A tomb(also,felso) résztömböt helycserék útján felosztjuk úgy, hogy tomb(also,kozep)<tomb(kozep+1,felso) A tömb első eleme az őr, a két résztömböt elválasztó érték. A két szélétől indulva növesztjük a kikötéseknek megfelelő résztömböket addig, amíg összeérnek
14
(rész)-Példa 5, 3, 2, 6, 4, 1, 3, 7 őr=5 5, 3, 2 | 6, 4, 1, 3 | 7 csere 63 5, 3, 2, 3, 4, 1| 6, 7 felosztva 1-6 között, tovább bal fél 5, 3, 2, 3, 4, 1 őr=5, pont a legnagyobb elem, alulról elindulva elérjük a lista utolsó elemét: csere 15 1, 3, 2, 3, 4 | 5 felosztva 4-5 között, tovább bal fél 1, 3, 2, 3, 4 őr=1 1 | 3, 2, 3, 4 felosztva 1-3 között, tovább jobb fél 3, 2, 3, 4 őr=3 3, 2 | 3, 4 felosztva 2-3 között, tovább bal fél 3, 2 őr=3 legnagyobb elem. Csere 32 3, 4 őr=3 legnagyobb elem: Csere 6 4
15
Hatékonyság: Legrosszabb felosztás
Legrosszabb eset, ha 1—n-l tömbökre osztunk fel Rekurziós fa: Felosztás: Θ(n), ezt n-szer kell megtenni: T(n)=T(n-1)+Θ(n) T(n)= i=1Σn Θ(i)= Θ(i=1Σn i)= Θ(n2) Maximálisan kiegyensúlyozatlan a felosztás n n-1 n-2 n-3 2 1
16
Hatékonyság: Kiegyensúlyozott felosztás
lg(n) 4*n/4 n/4 n/4 n/4 n/4 n*lg(n) Hatékonyság: Θ(n*lg(n)) hasonlóan pl. a kupacrendezéshez
17
Mitől függ a hatékonyság?
Mikor lesz 1..n-l felosztás? 1 | 4, 6, 7, 3, 2 az első a legkisebb/legnagyobb elem 6, 2, 5, 4, 3, 1 csere 6-1 1, 2, 5, 4, 3 | 6 Pl. a már sorbarendezett lista: extrém rossz Javaslat1: véletlen keverés O(n) időben Javaslat2: véletlen felosztás: Őrkifejezés a lista véletlen eleme legyen Az első elemet egy véletlen elemmel kicseréljük Veremmélység: a közölt rekurzív algoritmusra: Θ(log(n)) A rekurzió azonban kiküszöbölhető!!
18
Összehasonlító rendezések
A bemenő tömb rendezettségét az elemei közötti összehasonlítási reláción keresztül értelmezzük, és ezt végezzük el az elemek között… Döntési fa: csomópontjai a döntések, levelei az egyes lehetséges bemenő sorok. Rendezés: fabejárás gyökértől levélig (közben mozgatás) Leveleken: bemenő sorról teljes információ (permutáció) a1?a2 a2?a3 a1?a3 1,2,3 1,3,2 2,3,1 2,1,3 3,1,2 3,2,1 <= >
19
Összehasonlító rendezések
Lépések (összehasonlítások) száma: a fa magassága Tétel: n elemet rendező döntési fa Ω(n*log(n)) magas (legalább) Biz: tfh. n elemű sort rendező h magas fa. Levelek (permutációk) száma legalább n!. Fa leveleinek száma: <=2h n!<= 2h h>=lg(n!) Viszont (Stirling formula): n!>(n/e)n h>lg(n/e)n h> n*(lg(n)- lg(e)) = Ω(n*log(n)) Következmény: az nlog(n) rendezések (kupac- és összefésüléses rendezés) aszimptotikusan optimális rendezések
20
Lineáris időben lefutó rendezések Leszámláló rendezés
Feltétel: 1<elem<k egész szám Eredmény: O(n) Alapötlet: minden x elemre meghatározzuk az összes y<=x elemek számát. Ilyenkor az x elem helye n(y<=x) Helyigény: BEmenő tömb, GYakoriság tömb, KImenő tömb Fontos!! Stabil rendezés. Vagyis az azonos kulcsú elemek sorrendje nem változik
21
Leszámláló rendezés példa
BE: 3, 6, 4, 1, 3, 4, 1, 4 0<x<=6 (max) GY: 2, 0, 2, 3, 0, 1 gyakoriságok GY: 2, 2, 4, 7, 7, 8 összegezve KI: _, _, _, _, _, _, 4, _ BE-n visszafelé iterálunk KI: _, 1, _, _, _, _, 4, _ KI: _, 1, _, _, _, 4, 4, _ KI: _, 1, _, 3, _, 4, 4, _ KI: 1, 1, _, 3, _, 4, 4, _ KI: 1, 1, _, 3, 4, 4, 4, _ KI: 1, 1, _, 3, 4, 4, 4, 6 KI: 1, 1, 3, 3, 4, 4, 4, 6
22
Leszámláló rendezés programkód
Egyes értékek előfordulási gyakoriságai private int leszamlalMax = 30; public int[] leszamlal(int[] tomb,int meret) { int gy[] = new int[leszamlalMax]; int ki[] = new int[meret]; for(int i=1;i<leszamlalMax;i++) { gy[i]=0; } for(int i=1;i<leszamlalMax;i++) { gy[tomb[i]]++; } for(int i=2;i<leszamlalMax;i++) { gy[i]=gy[i]+gy[i-1]; } for (int i=meret-1;i>1;i--) { ki[gy[tomb[i]]--]=tomb[i]; } return ki; } Összegzett gyakoriságok. Hányan vannak előttem
23
Számjegyes rendezés Több helyiértékkel/több dimenzióval rendelkező mennyiség rendezése esetén, ha egy helyiérték csak véges felsorolás lehet (pl számjegyek) Helyigény: átpakoljuk az elemeket n db. vektorba Megoldás: a legkisebb helyiérték szerint rendezzük először, azután haladunk az egyre nagyobb helyiértékek felé Közben nem cserélhetünk fel egyes elemeket!!!
24
Számjegyes rendezés példa
ÓRA ÓRA LAP ÁGY LAP TEA LÁB FÜL TEA LÁB TEA GÉP GÉP ING GÉP ING ING FÜL KÉS KÉS SZÓ SZÓ ÁGY LAP FÜL LAP ING LÁB ORR GÉP SOR ORR LÁB ORR ORR ÓRA SOR SOR ÓRA SOR KÉS KÉS FÜL SZÓ ÁGY ÁGY SZÓ TEA
25
Edényrendezés Feltételezés: kulcsok egyenletesen oszlanak el az 0..1 intervallumban, a tömb n elemet tartalmaz Felosztjuk az intervallumot n egyenlő részre ezek lesznek az edények Hely: edénytároló n hosszú vektor Az egyes edényekben láncolt listákat kezelünk (ezek nem túl hosszúak), és ezeket valami egyszerű eljárással rendezzük Algoritmus: 1. Beszúrjuk az elemet a megfelelő edénybe 2. Az egyes edényeket rendezzük 3. Sorban összefűzzük az egyes edényeket
26
Edényrendezés - példa .78, .17, .39, .26, .72, .94, .21, .12, .23, .68 .94|* .72| .68|* .39|* .21| .12| .17|* .78|* .23| .26|* Hatékonyság: lineáris O(n) Miért? Az elemek egyenletes eloszlása miatt. Vagyis kevés a listában a luk, és a láncok pedig rövidek…
Hasonló előadás
© 2024 SlidePlayer.hu Inc.
All rights reserved.