De ce este std :: harta implementat ca un copac roșu-negru?

voturi
130

De ce este std :: harta implementat ca un arbore rosu-negru ?

Există mai multe echilibrate arbori binari de căutare (BSTs) acolo. Care au fost de proiectare compromisuri în alegerea unui copac roșu-negru?

Întrebat 13/03/2011 la 09:33
sursa de către utilizator
În alte limbi...                            


6 răspunsuri

voturi
86

Probabil cei doi algoritmi cele mai comune arbori autoechilibrare sunt copaci rosu-negru și copaci AVL . Pentru a echilibra copac după o inserție / actualizare algoritmi folosesc noțiunea de rotații în cazul în care nodurile arborelui sunt rotite pentru a efectua re-echilibrare.

În timp ce în ambele algoritmi insert / ștergere sunt O (log n), în cazul Roșu-negru rotație arbore de re-echilibrare este O (1) operarea în timp ce cu AVL este un O (log n) operarea, făcând roşu-negru copac mai eficient în acest aspect al etapei re-echilibrare și unul dintre motivele posibile pentru care este utilizat mai frecvent.

copaci roșu-negru sunt folosite în cele mai multe biblioteci de colectare, inclusiv ofertele din Java si Microsoft .NET Framework.

Publicat 13/03/2011 la 09:47
sursa de către utilizator

voturi
2

Este doar alegerea dvs. de implementare - acestea ar putea fi puse în aplicare ca orice arbore echilibrat. Diferitele alegeri sunt comparabile cu diferențe minore. Prin urmare, orice este la fel de bun ca oricare altul.

Publicat 13/03/2011 la 09:48
sursa de către utilizator

voturi
22

arbori AVL au o înălțime maximă de 1.44logn, în timp ce copacii RB au un maxim de 2logn. Introducerea unui element într-un AVL poate implica o reechilibrare la un moment dat în copac. Reechilibrarea termină inserția. După introducerea unei noi frunze, actualizarea strămoșii frunza trebuie făcut până la rădăcină, sau până la un punct în care cele două subramificații sunt de adâncime egală. Probabilitatea de a avea de a actualiza nodurile k este 1/3 ^ k. Reechilibrarea este O (1). Eliminarea unui element poate implica mai mult de o reechilibrare (până la jumătate din adâncimea copacului).

RB-arbori sunt B-arborii de ordine 4 reprezentate ca arbori de căutare binare. A 4-nod în rezultatele B-tree în două nivele în BST echivalent. În cel mai rău caz, toate nodurile arborelui sunt 2-noduri, cu un singur lanț de 3-noduri în jos la o frunză. Această frunză va fi la o distanță de 2logn de la rădăcină.

Mergând în jos de la rădăcină la punctul de inserare, trebuie să se schimbe 4-noduri în 2-noduri, pentru a vă asigura că orice inserție nu se va satura o frunză. Revenind la introducerea, toate aceste noduri trebuie să fie analizate pentru a vă asigura că acestea reprezintă în mod corect de 4 noduri. Acest lucru se poate face merge în jos în copac. Costul global va fi la fel. Nu există nici un prânz gratuit! Eliminarea unui element din arborele este de același ordin.

Toți acești copaci cer ca nodurile transporta informații cu privire la inaltime, greutate, culoare, etc. Numai copaci Splay sunt libere de astfel de informații suplimentare. Dar cei mai mulți oameni se tem de arbori splay, din cauza ramdomness structurii lor!

În cele din urmă, copaci pot transporta, de asemenea, informații de greutate în nodurile, permițând echilibrarea greutății. Diverse scheme pot fi aplicate. Unul ar trebui să reechilibreze atunci când un subarbore conține mai mult de 3 ori mai mare decât numărul de elemente ale celeilalte subarbore. Reechilibrarea se face din nou, fie throuh un singur sau dublu de rotație. Aceasta înseamnă că cel mai rău caz de 2.4logn. Se poate ajunge departe cu de 2 ori în loc de 3, un raport mult mai bine, dar aceasta poate însemna a lăsa un pic mai puțin de 1% din Thant subramificații dezechilibrat aici și acolo. Complicat!

Ce tip de copac este cel mai bun? AVL sigur. Acestea sunt cele mai simple de cod, și au înălțimea lor cea mai rea cea mai apropiată de logn. Pentru un arbore de 1000000 elemente, un AVL va fi la cea mai mare înălțime 29, un RB 40, și o greutate echilibrat 36 sau 50, în funcție de raportul.

Există o mulțime de alte variabile: intamplarea, raportul dintre adaugă, șterge, căutări, etc.

Publicat 16/07/2011 la 02:52
sursa de către utilizator

voturi
36

Este într-adevăr depinde de utilizare. AVL copac are de obicei mai multe rotații de reechilibrare. Deci, dacă cererea dumneavoastră nu are prea multe operații de inserare și ștergere, dar greutăți foarte mult pe căutarea, atunci copac AVL, probabil, este o alegere bună.

std::map foloseste copac rosu-negru ca acesta devine un compromis rezonabil între viteza nodului inserare / ștergere și căutarea.

Publicat 26/05/2012 la 19:32
sursa de către utilizator

voturi
2

Actualizați 2017-06-14: webbertiger edita răspunsul după ce am comentat. Ar trebui să subliniez faptul că răspunsul său este acum mult mai bine la ochii mei. Dar am păstrat răspunsul meu la fel ca și informații suplimentare ...

Datorită faptului că cred că primul răspuns este greșit (corecție: nu atât mai), iar al treilea are o afirmație greșită. Simt că a trebuit să se clarifice lucrurile ...

2 Cele mai populare copac sunt AVL și Red negru (RB). Principala diferență se află în utilizare:

  • AVL: O mai bună în cazul în care raportul de consultare (citire) este mai mare decât de manipulare (modificare). picior de imprimare de memorie este un pic mai puțin decât RB (datorită biți necesar pentru colorare).
  • RB: O mai bună în cazurile în general, în cazul în care există un echilibru între consultare (a se citi) și manipulare (modificare) sau mai multe modificări de peste consultare. O amprentă ușor mai mare de memorie datorită stocarea de steag roșu-negru.

Diferența principală provin de colorare. Tu ai mai puțin de acțiune re-echilibru în copac RB decât AVL, deoarece colorarea vă permit să săriți sau, uneori, să scurteze acțiunile de re-echilibru, care au un cost relativ hi. Din cauza de colorare, copac RB, de asemenea, mai ridicat nivel de noduri, deoarece ar putea accepta noduri roșii între cele negre (cu posibilitățile de ~ 2x mai multe niveluri) de luare de căutare (citit) un pic mai puțin eficient ... dar pentru că este o constant (2x), aceasta rămâne în O (log n).

Dacă ia în considerare lovit de performanță pentru o modificare a unui arbore (semnificativ) VS lovit de performanță de consultare a unui copac (aproape nesemnificativă), aceasta a devenit firesc să prefere RB peste AVL pentru un caz general.

Publicat 30/05/2017 la 20:33
sursa de către utilizator

voturi
5

Răspunsurile anterioare se referă doar la alternative de copac și roșu negru, probabil, rămâne doar din motive istorice.

De ce nu un tabel hash?

Într-un copac un tip necesită doar ordonare parțială (<comparație) pentru a fi utilizat ca o cheie în hartă. Cu toate acestea, tabele de dispersie cere ca fiecare tip de cheie are o funcție hash definită. Păstrarea acestor cerințe de tip la un nivel minim este foarte important pentru programarea generică.

Proiectarea unui tabel hash bun necesită o cunoaștere intimă a contextului acesta, care va fi utilizat. Ar trebui să-l folosească deschis adresare, sau înlănțuire legate? Ce niveluri de încărcare ar trebui să-l accepte înainte de redimensionare? Ar trebui să folosească un hash scump, care evită coliziuni, sau unul care este dur și rapid?

(C ++ 11 a adăugat tabele hash cu unordered_map. Puteți vedea din documentația este nevoie de setarea politicilor pentru a configura multe dintre aceste opțiuni.)

Deoarece STL nu se poate anticipa care este cea mai bună alegere pentru aplicația dvs., implicit trebuie să fie mai flexibil. Copaci „doar locul de muncă“ și scară frumos.

Ce zici de alți copaci?

Oferta de căutare rapid copac negru roșu și sunt auto-echilibrare, spre deosebire de BSTs. Un alt utilizator a subliniat avantajele sale peste copac auto-echilibrare AVL.

Alexander Stepanov (Creatorul STL) a spus că va folosi un arbore B * în loc de un copac roșu-negru dacă a scris std::mapdin nou. Acest lucru se datorează faptului că nodurile pot stoca un număr arbitrar de elemente contigue , care este mai prietenos pentru cache - uri de memorie moderne.

Una dintre cele mai mari schimbări de atunci a fost creșterea de cache-uri. ratări din cache sunt foarte costisitoare, astfel încât localitatea de referință este mult mai important acum. structuri de date bazate pe nod, care au scăzut localitate de referință, fac mult mai puțin sens. Dacă am fost proiectarea STL astăzi, aș avea un set diferit de containere. De exemplu, o B * -tree în memorie este o alegere mult mai bună decât un copac roșu-negru, pentru punerea în aplicare a unui container asociativ. - Alexander Stepanov

Puteți citi mai multe aici

Este roșu negru copac sau B * întotdeauna cel mai bun?

Cu alte ocazii , Alex a declarat că std::vectoreste aproape întotdeauna cea mai bună listă container din motive similare. Se face foarte rar sens să folosească std::listsau std::dequechiar și pentru acele situații ne - au fost predate în școală (cum ar fi eliminarea unui element din mijlocul listei). std::vectoreste atât de rapid încât bate acele structuri pentru tot , dar n mare.

Aplicând același raționament , dacă aveți doar un număr mic de elemente (sute?) , Folosind o std::vectorși căutarea liniară poate fi mai eficientă decât punerea în aplicare a arborelui std::map. În funcție de frecvența de inserție, o triate std::vectorcombinata cu std::binary_searchpoate fi cea mai rapidă alegere.

Publicat 22/12/2017 la 00:46
sursa de către utilizator

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more