Flerveis søketrær og B-trær
Flerveis (multi-way, n-ært) søketre Generalisering av binært søketre Binært søketre: Hver node har maksimalt 2 barn og 1 nøkkelverdi. Barna ligger sortert på verdi i forhold til den ene nøkkelverdien. Flerveis søketre (av orden * m): Hver node har maksimalt m barn og m 1 sorterte nøkkelverdier. Barna ligger sortert på verdi «innimellom» de sortete nøkkelverdiene. Brukes oftest når vi ikke får plass til alle data i primærhukommelsen/ram: Må lese fra/skrive til (aksessere) sekundærhukommelsen (disk) Diskaksess er veldig mye langsommere RAM-aksess Filsystemer i operativsystemer og databaser bruker flerveis søketrær som er optimaliserte for diskaksess *: «orden» er ikke entydig definert i litteraturen
Definisjon: Flerveis søketre av orden m Alle noder i treet har maksimalt m subtrær/barn I en node med k subtrær, S 1, S 2,..., S k, er det slik at: Noden inneholder k 1 nøkkelverdier, v 1, v 2,..., v k 1 som er sorterte: v 1 v 2... v k 1 Verdiene i subtrærne, v(s i ), ligger sortert slik at v(s i ) < v i v(s i + 1 ), i = 1, 2,..., k 2 v k - 1 v(s k ) Merk at subtrærne til en node kan være tomme
Et flerveis søketre av orden m = 5
Et flerveis søketre av orden m = 4
Flerveis søketre av orden m = 5
Innsetting og søking i flerveis søketre Samme prinsipp som for binære søketrær: Følger en vei fra roten og nedover i treet I hver node sjekker vi om verdien vi søker/skal sette inn er lik, mindre eller større enn de sorterte nøkkelverdiene i noden Går videre fra en node til det subtreet der verdien skal ligge, hvis den finnes i treet Hvis treet har totalt n verdier og er balansert, er søking og innsetting meget raskt O(log n) Hvis treet blir svært ubalansert, og/eller nodene i liten grad er fylt opp med verdier, blir søking og innsetting langsomt O(n)
B-tre 1 Et flerveis søketre som alltid er perfekt balansert og minst halvveis fylt opp med verdier (Bayer/McCreight,1972) Garanterer O(log n) oppførsel for søking, innsetting og fjerning Antall verdier i hver node er gjerne svært stort (tilsvarende en diskblokk/page) B-trær (og varianter som B+-trær og B*-trær) brukes i de fleste filsystemer (Windows, Mac, Unix/Linux) og i store databasesystemer 1: B?
Definisjon av B-tre Et B-tre av orden m er et flerveis søketre der: Roten er enten et blad eller har minst to subtrær Alle noder (unntatt roten) inneholder minst m/2 verdier og maksimalt m - 1 verdier En node med k verdier (m/2 k m - 1) har enten 0 barn (en bladnode) eller k + 1 barn (indre node) Alle bladnoder ligger på samme nivå i treet
B-tre av orden m = 5
B-tre av orden m = 5
Effektivitet, B-tre av orden m = 201 Antall noder og verdier i hvert nivå i treet
Søking i B-trær «An algorithm for finding a key in B-tree is simple. Start at the root and determine which pointer to follow based on a comparison between the search value and key fields in the root node. Follow the appropriate pointer to a child node. Examine the key fields in the child node and continue to follow the appropriate pointers until the search value is found or a leaf node is reached that doesn't contain the desired search value» Er garantert O(log n)
Innsetting av ny verdi i B-tre Kravet om at alle blader skal være på samme nivå gir en karakteristisk oppførsel for B-trær: B-trær vokser ikke «nedover» ved at de får nye blader, som for binære søketrær Istedet vokser de «oppover» ved at de får ny rot Nye verdier settes inn i eksisterende bladnoder Når en bladnode er full deles den i to, og en verdi sendes «oppover» i treet YouTube: Demo av innsetting i B-tre av orden m = 3, med maksimalt 2 verdier og 3 barn per node Innsetting er alltid O(log n)
Algoritme for innsetting i B-tre Finn bladnoden der ny verdi skal settes inn Hvis bladnoden ikke er full: Sett inn ny verdi sortert i bladnoden Ellers, hvis bladnoden er full av verdier: Del bladnoden i to noder, med ~halvparten av verdiene i hver node Send midterste verdi et nivå oppover for innsetting i foreldernoden Hvis foreldernoden også blir full, fortsettes sending av verdi(er) oppover i treet på samme måte
Eksempel: Innsetting i B-tre av orden m = 5
Etter innsetting av 395
Etter innsetting av 382
Etter innsetting av 490
Fjerning av verdi i B-tre Kan resultere i noder med for få verdier (< m/2) Vil lage et «hull» i strukturen hvis verdien som fjernes er i en indre node Algoritmen for fjerning «reparerer» treet med: Flytting av verdier mellom noder (aka rotasjoner) Sammenslåinger (merging) av to noder til én ny node Fjerning av verdier er vist i læreboka for B-trær med orden m = 3 (se avsnitt 12.2) Fjerning i B-trær er relativt «fiklete», med flere spesialtilfeller, men er alltid O(log n)
Implementasjon/lagring av B-trær En node i et B-tre av orden m kan representeres med to arrayer av lengde hhv. m og m 1: En array med referanser til barna En sortert array med nøkkelverdier B-trær brukes mest når data må flyttes mellom primær og sekundær hukommelse: Pekere til barn (adresser i RAM) vil ikke virke Vanlig i stedet å representere hele treet som én lang array, der referansene til barna er arrayindekser og det er satt av like stor plass til alle noder virker både i RAM og på disk
B-trær og sekundærhukommelse Hvis dataene våre er for store til å få plass i RAM, må de flyttes frem og tilbake mellom RAM/disk (paging) Lesing og skriving til/fra disk (flytting av lese-/ skrivehode, rotasjon av disk, dataoverføring) er ofte flere tusen ganger tregere enn å lese/skrive RAM Disker leses og skrives i «blokker», typisk 4K bytes om gangen (Linux) B-treet kan minimalisere antall diskaksesser: Størrelsen på en node «tunes» til blokkstørrelsen, slik at alle dataene i noden håndteres med én read/write operasjon
B*-trær Utnytter plassen på hvert nivå i treet bedre B*-treet har alle egenskapene til et B-tre, men: I et B-tre av orden m har alle noder minst m/2 verdier I et B*-tre av orden m har alle noder minst 2 m/3 verdier Algoritmene for innsetting og fjerning er forskjellige: I stedet for å dele en node i to med en gang den er full, flyttes verdier over til søskennoder Når to søskennoder er fulle av verdier, deles de i tre nye noder
B+-trær Løser et problem forbundet med vanlige B-trær: Traversering av et B-tre (sekvensiell/sortert gjennomgang av dataene) er vanskelig å gjøre effektivt når vi må skyfle data til/fra sekundærhukommelsen Hver node må oppsøkes mange ganger i løpet av en traversering av B-treet B+-tre: Alle nøkkelverdier i indre noder lagres en gang til som sin egen inorder etterfølger i en bladnode Alle bladnodene lenkes sammen med «pekere» for å kunne gå gjennom alle dataene sekvensielt/sortert med minimalt antall diskaksesser Lagrer oftest bare nøkkelverdier i treet, sammen med et ekstra lag med noder på nederste nivå som inneholder pekere/ referanser til selve dataobjektene
Eksempel: B+-tre
Eksempel: B+-tre