Arborele B

De la Wikipedia, enciclopedia liberă.
Salt la navigare Salt la căutare
Reprezentarea unui copac B.

Un copac B (în engleză : copac B ) este o structură de date care permite localizarea rapidă a fișierelor ( înregistrări sau chei), în special în baze de date , reducând de câte ori are nevoie un utilizator pentru a accesa memoria în care sunt salvate datele . Ele derivă din copacii de căutare binari , deoarece fiecare cheie aparținând subarborelui stâng al unui nod are o valoare mai mică decât orice cheie aparținând subarborelui din dreapta acestuia; în plus, structura lor garantează echilibrul lor: pentru fiecare nod, înălțimile subarborelui drept și stâng diferă cu mai mult de o unitate. Acesta este principalul avantaj al arborelui B și vă permite să efectuați operațiuni de inserare, ștergere și căutare în timpi amortizați logaritmic.

Acestea sunt adesea utilizate în contextul bazelor de date , deoarece permit accesul la noduri în mod eficient atât dacă sunt disponibile în memoria centrală (printr-un cache ), cât și dacă sunt prezente doar în memoria de masă.

Definiție

Un copac B este un copac înrădăcinat (a cărui rădăcină poate fi denumită ) care îndeplinește următoarele proprietăți:

  1. Fiecare nod are următoarele atribute:
    • , numărul de taste stocate în
    • indicând cu tasta a i-a a nodului da ai
    • este o valoare booleană care poate lua valoare dacă nodul este o frunză, in caz contrar.
  2. Fiecare nod intern are indicii copiilor săi.
  3. Merita
  4. Toate frunzele au aceeași adâncime (arborele este complet echilibrat )
  5. Numărul de chei pe nod este limitat în partea de sus și de jos. este gradul minim al arborelui
    • Fiecare nod conține cel puțin cheie
    • Fiecare nod conține cel mult cheie

Avantajele copacilor B

B-Trees aduce avantaje puternice în ceea ce privește viteza și eficiența față de implementările alternative atunci când majoritatea nodurilor se află în memoria secundară, de exemplu pe un hard disk. Prin maximizarea numărului de noduri copil pentru fiecare nod, înălțimea arborelui este redusă, operația de echilibrare este necesară mai rar și, prin urmare, crește eficiența. În general, acest număr este setat în așa fel încât fiecare nod să ocupe un întreg grup de sectoare: astfel, deoarece operațiunile de nivel scăzut accesează discul pe cluster, numărul de accesări la acesta este minimizat. Acestea oferă performanțe excelente atât în ​​ceea ce privește operațiunile de căutare, cât și de actualizare, deoarece ambele pot fi realizate cu complexitate logaritmică și prin utilizarea unor proceduri destul de simple. Pe ele este, de asemenea, posibilă efectuarea procesării secvențiale a arhivei primare fără a fi necesară reorganizarea acesteia.

Structura nodului

Este indicat cu ordinea pomului. Iată o simplificare a structurii nodului pentru un B-Tree implementat în C ++.

 struct bNode
{
  int nKeys ; // nivel de umplere nod
 
  bNode * RefPage [ 2 * R + 1 ]; // vector de indicatori către nodurile copil
 
  tipoChiave K [2 * R]; // vector comandat de chei 2 * R;
 
  lung RefInfo [ 2 * R ]; // vector de indicatori pentru arhivarea informațiilor
 
};

Înălțimea unui copac B.

Presupunând că numărul de chei al unui B-Tree este egal cu iar gradul său minim este , inaltimea , în cel mai rău caz, va fi

La urma urmei, dacă un B-Tree are înălțime , este evident că numărul nodurilor sale este minim dacă rădăcina conține o cheie și toate celelalte noduri conțin chei: veți avea, în acest fel, noduri la adâncimea 1, noduri la adâncimea 2, la adâncimea 3 și așa mai departe. Fix înălțimea Arborelui B va avea ca la adâncimea h să fie noduri. Deci, numărul de taste va fi

Crearea unui copac B.

Operația de creare a unui B-Tree (inițial fără chei) necesită doar crearea unui nod rădăcină.

 B-Tree-Create (T)
 alocați un nou nod x
 n [x] ← 0
 frunza [x] ← ADEVĂRAT
 scrie nodul x pe disc
 rădăcină [T] ← x

Operațiuni principale

Cele trei operații de bază care pot fi efectuate pe un B-Tree sunt discutate mai jos:

  • Căutați o cheie
  • Introducerea unei chei (necesită operația de divizare a nodului)
  • Ștergere (necesită îmbinarea nodurilor)

Cercetare

Căutarea unei înregistrări a cheii k se efectuează într-un mod similar cu arborele binar , cu singura diferență că, la fiecare pas, alegerile posibile nu sunt două, ci coincid cu numărul de chei ale fiecărui nod. Loc numărul de chei ale unui nod generic din Arborele B, vom avea acest lucru la fiecare nod intern vor apărea alegeri alternative.

Căutați o cheie

Procedura de căutare este împărțită în următorii pași:

  • Transferul rădăcinii în memorie
  • Căutați K în pagina transferată: dacă este prezentă, căutarea este finalizată.
  • În caz contrar, dacă K este mai mic decât cheia din stânga nodului, atunci transferați pagina indicată de indicatorul din stânga (dacă nu este nulă); dacă K este mai mare decât tasta din dreapta, atunci transferați pagina indicată de indicatorul din dreapta (dacă nu este nulă); dacă este între două taste ale nodului, atunci transferați pagina indicată de pointer între cele două taste (dacă nu este nulă). Reveniți la punctul 2.
  • Dacă indicatorul în cauză este nul, cheia nu este prezentă.

În acest fel, numărul maxim de pagini care trebuie citite pentru căutare coincide cu înălțimea arborelui.

Procedura B-Tree-Search (x, k) caută o cheie a Arborelui B începând de la un nod .

 B-Tree-Search (x, k)
 i ← 1
 în timp ce i <= n [x] && k> tasta i [x] fac
   i ← i + 1
 dacă i <= n [x] && k = cheia i [x] atunci
   return (x, i)
 dacă frunza [x] atunci
   întoarceți NIL
 altceva
   citiți nodul c i [x] de pe disc
   returnează B-Tree-Search (c i [x], k)

Deoarece în procedura de căutare arborele B este traversat de-a lungul unei căi de la rădăcină la o frunză, numărul de accesări pe disc este egal cu . În plus , prin urmare, timpul de execuție al algoritmului este, în mod trivial, .

Inserare

Introducerea unei noi chei poate fi mai dificilă decât aceeași procedură pentru un arbore binar, deoarece este esențial să se mențină echilibrul arborelui. O operație preliminară, care trebuie implementată în mod adecvat, pentru a putea îndeplini o funcție pentru inserarea unei chei într-un Arborele B este operația de împărțire a unui nod solid. Un nod al unui B-Tree este definit ca plin dacă conține exact chei: fiind plin, în timpul fazei de inserare a unei chei, nu poate, prin însăși definiția arborelui B, să fie inserat în interiorul ei. Operația de divizare se efectuează la cheia mediană a nodului deplin. După împărțire, nodul complet este împărțit în două noduri diferite fiecare cu cheie. Mai exact, cheia mediană a nodului este mutat la părintele nodului (nu plin). Operația de împărțire a unui nod crește în mod clar înălțimea copacului.

 B-Tree-Split-Child (x, i, y)
 alocați nodul z
 frunze [z] ← frunze [y]
 n [z] ← t-1
 pentru j ← 1 până la t-1
faceți tasta j [z] ← tasta j + t [y]
 dacă nu frunza [y]
apoi pentru j ← 1 la t
 faceți c_j [z] ← c j + t [y]
 n [y] ← t-1
 pentru j ← n [x] +1 până la i + 1
faceți c j + 1 [x] ← c j [x]
 c i + 1 [x] ← z
 pentru j ← n [x] până la i
faceți tasta j + 1 [x] ← tasta j [x]
 tasta i [x] ← tasta t [y]
 n [x] ← n [x] +1
 scrieți nodurile y, z, x pe disc

Operațiunea de introducere a unei chei se realizează grație unei vizite la copac care, prin exploatarea procedurii de împărțire a nodului, împiedică introducerea acestuia într-un nod deja complet. La primul pas al procedurii de inserare se verifică dacă rădăcina arborelui B este plină: în acest caz este împărțită la înălțimea cheii mediane; acesta din urmă va deveni singura cheie a unui nou nod rădăcină; în acest moment, procedura de inserare propriu-zisă poate fi realizată prin intermediul unei funcții recursive speciale care se ocupă de introducerea cheii în poziția corectă. Dacă rădăcina arborelui, pe de altă parte, nu este plină, puteți continua direct cu inserarea. În acest scop, pot fi implementate două proceduri: B-Tree-Insert care are grijă să verifice dacă rădăcina este plină sau nu și B-Tree-Insert-Nonfull care se ocupă de efectuarea vizitei recursive a copacului pentru a insera introduceți corespondența corectă. Această ultimă procedură este invocată oricum de prima procedură, dar dacă rădăcina este plină, aceasta este divizată preliminar. Să presupunem că doriți să introduceți o cheie într-un copac B. .

 B-Tree-Insert (T, k)
 // dacă rădăcina este plină
 dacă n [r] = 2t-1
apoi alocați un nod s
 rădăcină [t] ← s // nodul s va fi noua rădăcină
 leaf [s] ← FALS
 n [s] ← 0
 c 1 [s] ← r
 // divizarea nodului r (anterior a fost rădăcina)
 B-Copil-Split-Copil (s, 1, r)
 // apelează procedura de inserare recursivă începând cu s
 B-Tree-Insert-Nonfull (s, k)
// dacă rădăcina nu este plină
altceva
 // apelează procedura de inserare recursivă începând de la r
 B-Tree-Insert-Nonfull (r, k)

Procedura B-Tree-Insert-Nonfull introduce cheia într-un nod nu este plin de arborele B.

 B-Tree-Insert-Nonfull (x, k)
// dacă nodul x este o frunză
dacă frunza [x]
 atunci
  // derulați printre tastele lui x pentru a găsi poziția corectă pentru k
  în timp ce i> = 1 && k <tasta i [x]
 do
  tasta i + 1 [x] ← tasta i [x]
  i ← i-1
  // introduceți cheia
  tasta i + 1 [x] ← k
  // actualizare câmp n [x]
  n [x] ← n [x] +1
  scrie nodul x pe disc
 // dacă nodul x nu este o frunză, trebuie să determinăm care
 // subarborele procedează recursiv în funcție de valoarea lui k
 altceva
  în timp ce i> = 1 && k <tasta i [x]
 do
  i ← i-1
  i ← i + 1
  // nodul a fost găsit
  citiți nodul c i [x] de pe disc
  // dacă nodul este plin
  dacă n [c i [x]] = 2t-1
 // împărțirea nodului
 apoi B-Tree-Split-Child (x, i, c i [x])
  dacă k> tasta i [x]
atunci
  i ← i + 1
  // dacă nodul nu este plin sau a fost deja împărțit, puteți
  // continuați recursiv cu vizita
  B-Tree-Insert-Nonfull (c i [x], k)

Complexitatea algoritmului de inserare într-un B-Tree trebuie evaluată în funcție de numărul de accesări pe disc atât pentru citirea nodurilor, cât și pentru scriere. Presupunând că înălțimea Arborelui B este se execută procedura B-Tree-Insert accesări pe disc. Timpul de execuție este egal cu .

Anulare

Procedura de ștergere a unei chei este inversa procedurii de inserare a acesteia. Să presupunem că trebuie să ștergeți o cheie dintr-un subarbore înrădăcinat : în acest caz o procedură de ștergere este apelată recursiv pe nod numai dacă numărul de taste al este egal cu gradul minim al arborelui B. . Cazurile care pot fi întâlnite atunci când doriți să ștergeți o cheie dintr-un B-Tree sunt diverse.

  • Dacă cheia se află în nod și este o frunză, apoi ștergeți cheia fără operațiuni ulterioare (caz banal).
  • Dacă cheia se află într-un nod intern atunci procedura este mai complexă. Există trei subcazuri diferite (dintre care două sunt simetrice).
    • Este fiul lui de mai sus ; de sine are cel puțin tastele pe care trebuie să le găsiți pe predecesorul în subarborele care are ca rădăcină ; a găsit-o pe cea din urmă și a indicat cu este șters și ulterior înlocuit cu în .
    • Caz simetric cu cel precedent. Este fiul lui care urmează ; de sine are cel puțin chei de care aveți nevoie pentru a găsi succesorul în subarborele care are ca rădăcină ; a găsit-o pe cea din urmă și a indicat cu este șters și ulterior înlocuit cu în .
    • Lasa-i sa fie Și respectiv copiii care preced și reușesc și presupune că au cheie. Apoi, acestea trebuie inserate în nod este cheia că toate cheile din ; în acest caz copiii din devin copii ai . Cu toate acestea nodul pierde și indicatorul către iar nodul devine plin. Prin urmare, este necesar să se procedeze recursiv pentru a elimina din .
  • De sine nu este prezent în atunci se determină rădăcina a subarborelui pe care îl conține . Există două sub-cazuri.
    • De sine are chei și un nod soră cu tastele apoi la o cheie a tatălui și apoi iei o cheie fie de la fratele drept, fie de la fratele stâng al . Mai târziu îl mută pe fiul potrivit de la fratele său și se potrivește .
    • De sine iar frații săi au se amestecă cu unul dintre frații săi. O cheie a va coborî în noul nod devenind mediana sa.

Complexitatea algoritmului de ștergere în ceea ce privește accesul la disc este în timp ce complexitatea timpului este .

Variante ale arborelui B.

Există mai multe variante ale arborelui B. Cele mai frecvente trei sunt:

  • Arborele B +
  • Arborele B *
  • Prefixul arborelui B
  • Arborele predictiv B +

Copac B +

Spre deosebire de arborele B, în arborele B + toate datele sunt salvate în frunze. Nodurile interne conțin doar chei și pointeri. Toate frunzele sunt la același nivel. Nodurile de frunze sunt, de asemenea, legate între ele ca o listă pentru a facilita extragerea informațiilor. Această conexiune face, de asemenea, posibilă efectuarea de interogări pentru o serie de valori admisibile într-un mod eficient. Numărul maxim de taste dintr-o înregistrare se numește ordinea R a arborelui B +. Numărul minim de taste pentru fiecare înregistrare este R / 2. Numărul de taste care pot fi indexate folosind un copac B + este o funcție a lui R și a înălțimii copacului. Pentru un copac B + de ordinul și înălțimea h:

  • Numărul maxim de taste este
  • Numărul minim de taste este

Dintre toate variantele arborelui B, acesta este cel mai utilizat, deoarece toate primele noduri interne pe care le poate conține memoria principală sunt păstrate pe acesta, în timp ce restul nodurilor și frunzelor sunt lăsate în memoria de masă. Aceasta permite o viteză de căutare mai mare.

Acest tip de structură se aplică în sistemul de fișiere Journaled File System , HPFS , fi sistem de fișiere , ReFS , ReiserFS și XFS .

B * copac

Un arbore B * este o structură de date dezvoltată pentru gestionarea unor cantități mari de informații, este compusă din 2 părți: directorul și arhiva.

  • Arhiva este alcătuită din înregistrări, fiecare dintre ele putând fi văzută ca o pereche cheie-informație.
  • Directorul este organizat ca un copac: frunzele conțin indexuri, adică perechile cheie-pointer care vă permit să localizați înregistrările din arhivă, în timp ce partea superioară a arborelui are singura sarcină de a conduce la identificarea rapidă a indexul care conține cheia căutată.

Varianta principală, totuși, constă în frunzele copacului, care sunt conectate între ele printr-un lanț de indicatori, astfel încât să permită o scanare secvențială a arhivei.

Acest tip de structură își găsește aplicarea în cele Reiser4 , HFS , HFS Plus și Btrfs fișier sisteme .

Prefixul arborelui B.

Prefixul arborelui B este o evoluție a arborelui B *. În prefixele arborelui B nodurile de director nu conțin neapărat chei întregi, ci separatoare generice, adică chei care ar fi putut fi private de partea lor inițială (prefixul); întreaga cheie poate fi reconstituită pornind de la separatorul corespunzător, cunoscând poziția în arborele nodului în care este conținută. Frunzele arborelui conțin în schimb chei întregi, pentru a face căutarea secvențială mai eficientă.

Arborele predictiv B +

Pictogramă lupă mgx2.svg Același subiect în detaliu: arborele predictiv B + .

Bibliografie

  • Renato Conte, Lumea obiectelor Vol. 2
  • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Introducere în algoritmi . Jackson Books, 2003, ISBN 88-256-1421-7 .

Elemente conexe

Alte proiecte

linkuri externe

Informatică Portal IT : accesați intrările Wikipedia care se ocupă cu IT