Miskolci Egyetem Informatikai Intézet Általános Informatikai Tanszé k Pance Miklós Adatstruktúrák, algoritmusok előadásvázlat Miskolc, 2004 Technikai közreműködő: Imre Mihály, műszaki informatikus hallgató
B-fák Nem bináris fa. Az M-ed rendű B-fa a következő szerkezeti tulajdonságú fa: a gyökér vagy levél, vagy 2 és M közötti gyereke van, minden nem levél csúcsnak a (gyökér kivételével) [M/2] és M közötti gyereke van, minden levél azonos mélységben van. Minden adatot a levelekben tárolunk. Minden belső csomópontban a gyerekekre mutató P 1, P 2,..., P M pointereket, és azokat a legkisebb k 1, k 2,..., k M-1 kulcsértékeket tároljuk, melyek P 2, P 3,..., P M alfákban találhatóak. Természetesen ezen mutatók nil-ek is lehetnek és akkor a megfelelő kulcsérték definiálatlan. 2
B-fák Minden csúcsra a P 1 alfában található összes kulcs kisebb a P 2 alfában található kulcsoknál, és így tovább. A levelek a tényleges adatokat tartalmazzák, amik vagy maguk a kulcsok, vagy a kulcsot tartalmazó rekordra mutató pointerek. Ennek a definíciónak léteznek variációi, de ez a legáltalánosabban elfogadott. Most azt is kikötjük, hogy a levelekben [M/2] és M közötti kulcs legyen. 3
B-fák A 4-ed rendű B-fát szokták fának is nevezni, pl.: , 4, 8, 1112, 13 15, 18, 19 21, 2425, 2631, 3841, 43, 4648, 49, 5059, 6872, 78 84, 88 91, 92, 99
B-fa műveletek A B-fa műveleteit egy 2-3 fán mutatjuk be: a belső pontok, levél a kulcsokkal:, a leveleken a kulcsok rendezettek : - 16 : - 41 : 58 8, 11, 12 16, 1722, 23, 3141, 52 58, 59, 61 Keresés: a gyökértől indul, összehasonlít, megy tovább...
B-fa műveletek Beszúrás: keresés a levélig, pl. a 18, majd az 1 beszúrása: a levélen 4 érték lenne (maximum 3 lehet) kettévágjuk és a szülők információit kiigazítjuk: 6 22 : - 11 : : 58 11, 12 16, 17, 1822, 23, 3141, 52 58, 59, 61 1, 8
B-fa műveletek Az 19 beszúrásánál a szülő csúcsot is ketté kell vágni: 7 22 : - 41 : 58 22, 23, 3141, 52 58, 59, : 16 11, 12 16, 171, 8 18, 19 22, 23, 3141, 52 58, 59, : - 11, 12 16, 171, 8 18, : - 41 :58 16 : 22
B-fa műveletek Az 28 beszúrásánál a nagyszülő csúcsot (gyökér) is ketté kell vágni, a fa magassága eggyel nő: 8 22, 2328, 31 58, 59, : - 11, 12 16, 171, 8 18, : - 41 :58 16 : 22 41, 52
B-fa műveletek 9 28 : - 58 : - 16 : : - 18 : - 16 : - 28 : - 58 : - 41 : - 22 : - 22, 23 28, 3141, 52 58, 59, 61
B-fa műveletek Csak az elérési úton kell változtatásokat végezni és ez az útvonal hosszával arányos. Egy más módszer a túlterhelés kezelésére (bár az előző talán a legegyszerűbb), a kettévágás helyett először megpróbálunk egy kétkulcsos testvért keresni. Pl. a 70 beszúrását végezhetjük úgy is, hogy az 58-at áttesszük a baloldali testvérhez: és a szülőknél is aktualizálunk: 58 59. Ez a stratégia a belső csúcsokban is alkalmazható. Így a csúcspontok telítettebbek lesznek. Egy kicsit bonyolultabb a rutin, de kevesebb tárolóhelyet vesztegetünk , 52, 58 59, 61, 70
B-fa műveletek Törlés: megkeressük, eltávolítjuk, ha egy érték maradna akkor, ha a testvérének 3 kulcsa van, akkor egyet ellopunk, 2 kulcsa van, akkor összevonjuk őket. a szülő vesztett egy gyereket, felbugyborékoltatjuk a gyökérig, ha a gyökérnek már csak egy gyereke marad, akkor töröljük a gyökeret, csökken a magasság. Általában az M-ed rendű B-fánál, a kulcs beszúrásánál akkor van gond, ha a csúcsnak (ahová való) már M kulcsa van. A B-fa maximális mélysége [log [M/2] N]. Az útvonal minden csúcsában O(log M) munkával választjuk ki a megfelelő ágat (bináris kereséssel). Az Insert vagy Delete O(M) munkát igényelhet a csúcspontban. Így a legrosszabb esetben O(M log M N) =O( M * log N / log M), a keresés pedig O(log N) hatékonyságú. 11
B-fa műveletek Empirikusan az M=3,4 a legjobb, ha csak fő memóriát használunk. Adatbázis rendszereknél a fát lemezen tároljuk. A lemez műveletek száma O(logM N), ezen belül a keresés O(log M), de ez most a lemez művelet idejénél nagyságrendekkel kisebb. Ezért az M értékét úgy választjuk, hogy egy csomópont adatai egy blokkot foglaljanak el: 32 <= M <= 256. Mivel egy ilyen fa mélysége 2,3,..., nagyon kevés lemez művelet kell (a gyökér és talán az első szint is a memóriában lehet). Analízisek mutatják, hogy ajánlatos a B-fát 69%-ig telíteni (log 2) és hatásos a testvér kihasználása is, a kettévágás helyett. 12
B + -fa A B + -fa testvér mutatókat is alkalmaz. 13