B-fa Felépítés, alapvető műveletek előadás http://nik.uni-obuda.hu/prog2 Szénási Sándor szenasi.sandor@nik.uni-obuda.hu Óbudai Egyetem,Neumann János Informatikai Kar
B-fa Felépítése Beszúrás művelete Törlés művelete
3 B-fa B-fa: Olyan kiegyensúlyozott keresőfa, amelyet úgy terveztek, hogy hatékonyan lehessen alkalmazni háttértárolón tárolt adatok esetén is Gyakorlati szempontból a futási időt két összetevőre bontjuk fel lemezhozzáférések száma központi egység műveleteinek száma Napjainkban alkalmazott háttértárolók általában nagyságrendekkel nagyobb sebességet tudnak elérni blokkok írása/olvasása során, mintha ugyanezt az adatmennyiséget elemi adatokként írnák/olvasnák A keresés során tehát egy optimalizálási lehetőség, ha a lemezhozzáférések számát blokkonkénti kezeléssel próbáljuk csökkenteni
4 B-fa egy csúcsának felépítése n egész szám : a csúcsban tárolt kulcsok darabszáma (a rá vonatkozó korlátokat lásd következő oldalon) levél - logikai érték : levélről vagy belső csúcsról van szó kulcs 1 kulcs 2... kulcs n K összehasonlítható típus : a csúcsban tárolt kulcsok listája (minden kulcs egyedi) tartalom 1, tartalom 2,, tartalom n - T típus : a tartalom, a példákban mindig feltételezzük, hogy a kulcsokkal együtt mozog gyerek 1, gyerek 2,...,gyerek n+1 M típus : hivatkozások a csúcs gyerekeire (részfáira) k 1 k 2 k 3 k 4 k 5 k 6 k 7 gy 1 gy 2 gy 3 gy 4 gy 5 gy 6 gy 7 gy 8
5 B-fa további jellemzői Ha k i egy kulcs a gyerek i gyökerű részfában, akkor: k 1 kulcs 1 k 2 kulcs 2... k n kulcs n k n+1 A csúcsokban található kulcsok darabszáma alulról és felülről is korlátos, ezt egy rögzített t számmal lehet kifejezni (B-fa minimális fokszáma): Minden nemgyökér csúcsnak legalább t-1 kulcsa van, tehát minden belső csúcsnak legalább t gyereke Minden csúcsnak legfeljebb 2t-1 kulcsa lehet, tehát minden belső csúcsnak legfeljebb 2t gyereke A kulcsok darabszámára más módon is adhatunk korlátot, mi mindig ezt a definíciót használjuk (egyes szakirodalmak azonban ettől eltérhetnek) A B-fa mindig kiegyensúlyozott: minden levél mélysége azonos
B-fa példa szenasi.sandor@nik.uni-obuda.hu 6 gyökér N C F I Q T A B D E G H J K O P R S W X A példában t = 3, tehát a gyökércsúcs kivételével a csúcsokban található kulcsok száma minimum 2 maximum 5
7 B-fa csúcsának szétvágása - példa B-fa csúcsának szétvágása (t = 4) y = x.gyerek i y x A I U B C D E F G H T 1 T 2 T 3 T 4 T 5 T 6 T 7 T 8 x A E I U y = x.gyerek i z = x.gyerek i+1 y B C D F G H z T 1 T 2 T 3 T 4 T 5 T 6 T 7 T 8
8 B-fa csúcsának szétvágása A szétvágás lépései Új z csúcs létrehozása Az y utolsó t-1 db kulcsának (és ha van, gyerek mutatójának) átmásolása z-be Az y így maradt legnagyobb kulcsának felvitele x-be A z csúcs legyen x gyereke a 3. pontban felvitt kulcs után Megjegyzés: y telített, x nem telített A vágáshoz szükség van egy hivatkozásra az elem szülőjére. Ezt vagy minden elemben eltároljuk, vagy az algoritmusnak kell nyilvántartania Speciális eset: gyökér szétvágása A lépések hasonlóak a fentihez Ezt követően a gyökér elem az újonnan létrehozott elem lesz
9 B-fába új elem beszúrása Mindig levélbe szúrjuk be az új kulcsot, azonban ez csak akkor lehetséges, ha a megfelelő levél még nem telített Ezt már a keresés fázisban biztosítjuk, telített elemre nem lépünk tovább, hanem szétvágásokkal garantáljuk a megfelelő elemszámot Rekurzív megoldás: x gyökerű B-fába akarunk egy K kulcsot beszúrni Ha x egy levélelem Az x csúcs K-nál nagyobb kulcsainak (és tartalmak) hátraléptetése Új K kulcs (és ha van tartalom) felvétele az x kulcsai közé Az x csúcs n mezőjének növelése Ha x nem levélelem x kulcsai alapján megkeressük, hogy a K kulcs helye melyik y részfában van Ha ennek gyökere telített, akkor ezt szétvágjuk, és újra elvégezzük az y részfa keresést (a két új részfa közül melyikbe kell továbblépni) Folytatjuk a rekurzív beszúrást: y gyökerű részfába K kulcs beszúrása Speciális esetek: Első elem beszúrása új gyökérelem létrehozása és K elhelyezése x a gyökérelem és telített szétvágás és új gyökérelem létrehozása a régi gyökér középső elemével
10 Levélbe kulcs beszúrása Példa: F beszúrása (t = 4) A O U... B C D E H I...... A O U... B C D E F H I......
11 Telített csúcsra lépés előtti szétvágás Példa: G beszúrása (t = 4) A O U... B C D E F H I...... A E O U... B C D F G H I......
12 Telített gyökérelem esetén új gyökér Példa: X beszúrása (t = 4) B C D E F G H................ E B C D F G H................X
13 Fa magassága a beszúrások során Az első elem beszúrásakor a fa magassága 1 lesz egyetlen csúcsponttal, tehát ilyenkor kiegyensúlyozott Az egyes levelekbe való beszúráskor nem változik a fa csúcsainak szerkezete, tehát a kiegyensúlyozottságot ez nem befolyásolja A gyökércsúcs kettévágása az egyetlen művelet, amely a B-fa magasságát növeli. Ez azonban minden levélhez vezető út hosszát ugyanúgy egyel növeli, így a kiegyensúlyozottság ebben az esetben is megmarad A bináris keresőfával ellentétben tehát a B-fa a gyökerénél nő, és nem a fa alján Ennek köszönhetően a B-fa mindig kiegyensúlyozott
14 B-fából elem törlése Cél: K kulcsot tartalmazó csúcs megkeresése, majd innen a K törlése Rekurzív megoldás: x gyökerű B-fából akarunk egy K kulcsot törölni Ha K nincs az x-ben, akkor az x kulcsai alapján megkeressük, hogy melyik részfában kell lennie, és rekurzívan ott folytatjuk a törlést (még pontosítjuk!) Ha K az x-ben van és x egy levélelem K kulcs (és tartalom) törlése x-ből Az x csúcs K-nál nagyobb kulcsainak (és tartalmak) előre léptetése Az x csúcs n mezőjének csökkentése Ha K az x-ben van és x belső csúcs i) eset: ha van x-nek olyan y gyökerű részfája, amely tartalmaz egy K-t közvetlenül megelőző K kulcsot, és y-nak legalább t kulcsa van: az x-beli K kulcs felülírása K -vel (tartalom is), és a törlés rekurzív folytatása: az K kulcsot töröljük az y gyökerű részfából ii) eset: hasonló mint i) csak a K-t közvetlenül követő kulcsot keressük meg iii) eset: ha az i) és ii)-ben vizsgált mindkét szomszédos gyereknek csak t-1 kulcsa van, akkor töröljük a K kulcsot (és a tartalmat) x-ből és egyesítjük a két gyereket és a törölt K-t egy közös y csúcsban (ami továbbra is az x gyereke), majd rekurzívan folytatjuk: K kulcsot töröljük az y gyökerű fából
15 Feltétel biztosítása Vegyük észre, hogy az előző levélből törlés és a iii) eset csak akkor működik, ha az x-ben lévő kulcsok száma legalább t Mivel ez alapból nem biztos hogy fennáll, ezért ezt már a keresés során garantálnunk kell az alábbiak szerint: az újabb rekurzív hívás előtt ha azt látjuk, hogy a következő vizsgálandó y csúcsnak csak t-1 kulcsa van, de valamelyik testvérének t, akkor a testvérből vigyünk fel egy kulcsot a szülőbe (ez most az x), onnan pedig egyet le az y-ba. ha a következő csúcsnak és egyik testvérének is t-1 kulcsa van, akkor egyesítsük ezeket, és vigyünk le az így feleslegessé vált kulcsot a szülőből Speciális esetek: Nincs törlendő kulcs a fában hibát jelzünk Ha az x a gyökér és mindkét gyerekének t kulcsa van a fenti műveletek elvégzése, és az így kapott új csúcs lesz az új gyökér B-fa egyetlen elemének törlése gyökér -ra állítása Megjegyzés: csak a gyökér utolsó kulcsa és annak gyerekei összevonásakor változik a fa magassága, ezzel meg tudja őrizni a kiegyensúlyozottságot
16 B-fa további műveletei Bejárás Alapelve hasonló a bináris fáknál megismerttel, Kibővítve azzal, hogy egy csúcsnak több tartalma és gyereke lehet, így csúcsokon belül is egy ciklust kell indítani Keresés Alapelve hasonló a bináris fáknál megismerttel, Kibővítve azzal, hogy egy csúcsnak több tartalma és gyereke lehet, így csúcsokon belül is egy ciklust kell indítani A kulcsok rendezettek, ezért csúcson belüli kereséskor használható a logaritmikus keresés Keresés hatékony, mivel A fa mindig kiegyensúlyozott, így biztosítható az ideális keresési lépésszám Mivel egy csúcs több kulcsot tartalmaz, így kevesebb csúcsbetöltést igényel, ezzel kevesebb háttértár műveletet
17 Irodalomjegyzék Javasolt/felhasznált irodalom Cormen, Leiserson, Rivest: Algoritmusok, Műszaki Könyvkiadó, 1997 Pap, Szlávi, Zsakó: μlógia27 Rekurzív típusok: Adattípusok, ELTE TTK, 1994 Szénási: Algoritmusok, adatszerkezetek II., Óbudai Egyetem, 2014