Albero nero rosso sopra l'albero di avl


109

Gli alberi AVL e rosso nero sono entrambi autobilanciati tranne il colore rosso e nero nei nodi. Qual è il motivo principale per scegliere alberi neri rossi invece di alberi AVL? Quali sono le applicazioni degli alberi neri rossi?



1
Per inciso, gli sviluppatori di Rust hanno scelto di utilizzare un B-tree invece di uno di questi per la loro mappa ordinata standard.
Tom Anderson

Risposte:


124

Qual è il motivo principale per scegliere alberi neri rossi invece di alberi AVL?

Entrambi gli alberi rosso-neri e alberi AVL sono i più comunemente utilizzati bilanciati alberi binari di ricerca e supportano l'inserimento, la cancellazione e look-up in garanzia O(logN) time. Tuttavia, ci sono i seguenti punti di confronto tra i due:

  • Gli alberi AVL sono più rigidamente bilanciati e quindi forniscono ricerche più veloci. Pertanto, per un'attività di ricerca intensiva, utilizzare un albero AVL.
  • Per un'attività intensiva di inserimento, utilizzare un albero rosso-nero.
  • Gli alberi AVL memorizzano il fattore di equilibrio in ogni nodo. Questo richiede O(N)spazio extra. Tuttavia, se sappiamo che le chiavi che verranno inserite nell'albero saranno sempre maggiori di zero, possiamo utilizzare il bit di segno delle chiavi per memorizzare le informazioni sul colore di un albero rosso-nero. Pertanto, in questi casi l'albero rosso-nero non occupa spazio aggiuntivo.

Quali sono le applicazioni dell'albero rosso nero?

Gli alberi rosso-neri hanno uno scopo più generale. Funzionano relativamente bene con l'aggiunta, la rimozione e la ricerca, ma gli alberi AVL hanno ricerche più veloci al costo di una più lenta aggiunta / rimozione. L'albero rosso-nero viene utilizzato nel seguente:

  • Java: java.util.TreeMap,java.util.TreeSet
  • C ++ STL (nella maggior parte delle implementazioni): map, multimap, multiset
  • Kernel Linux: scheduler completamente equo, linux / rbtree.h

43
In general, the rotations for an AVL tree are harder to implement and debug than that for a Red-Black tree.non è vero.
Jingguo Yao

9
Per essere pedanti, lo standard C ++ non lo impone std:: mape gli amici usano una struttura particolare. Questo è lasciato all'implementazione, sebbene libstdc ++ e Dinkumware utilizzino almeno alberi rosso-neri, e sembra che tu abbia ragione in pratica.
mbozzi

25
Il fattore di bilanciamento memorizzato in ogni nodo di un albero AVL è di due bit (-1 / 0 / +1). Un albero rosso-nero memorizza un bit di informazioni sul colore in ogni nodo. Quindi in totale entrambi gli alberi richiedono una memoria O (N) per le informazioni aggiuntive.
Seppo Enarvi

5
"Per un inserimento intensivo di attività, utilizzare un albero rosso-nero." Perché? Nel peggiore dei casi, l'inserimento dell'albero AVL richiede solo una rotazione, mentre l'albero rosso nero può richiederne due.
Daniel

3
Questo dovrebbe essere aggiornato in base all'analisi di Ben Pfaff del 2003 sulle prestazioni BST: gli alberi AVL hanno uno scopo più generale e funzionano meglio. Sarebbe interessante rintracciare le ragioni storiche esatte per Java, C ++ e il kernel Linux che scelgono l'implementazione più lenta.
David McManamon

16

Prova a leggere questo articolo

Offre alcune buone informazioni su differenze, somiglianze, prestazioni, ecc.

Ecco una citazione dall'articolo:

Gli alberi RB sono, così come gli alberi AVL, autobilanciati. Entrambi forniscono prestazioni di ricerca e inserimento O (log n).

La differenza è che gli alberi RB garantiscono O (1) rotazioni per operazione di inserto. Questo è ciò che in realtà costa le prestazioni nelle implementazioni reali.

Semplificato, gli RB-Trees ottengono questo vantaggio dall'essere concettualmente 2-3 alberi senza portare in giro il sovraccarico delle strutture dinamiche dei nodi. Fisicamente gli RB-Trees sono implementati come alberi binari, i flag rosso / nero simulano 2-3 comportamenti

Per quanto ne so, gli alberi AVL e RB non sono molto distanti in termini di prestazioni. Un albero RB è semplicemente una variante di un albero B e il bilanciamento è implementato in modo diverso da un albero AVL.


1
AFIAK, un albero AVL ha anche una rotazione O (1) per inserimento. Per RB-tree e AVL - un inserimento può avere 1 o 0 rotazioni. Se avviene la rotazione, gli algoritmi si interrompono. Se non accade, di solito, gli algoritmi continuano a controllare / ridipingere i nodi dal basso alla radice dell'albero. Quindi, a volte la rotazione O (1) può essere migliore perché elimina la scansione degli elementi rimanenti O (log (n)). Poiché l'albero AVL, in media, fa più rotazione, l'albero AVL è, di solito, ha un equilibrio migliore ~ ​​1,44 log (N) rispetto a RB-albero 2 log (N).
Sergey Shandar

4

La nostra comprensione delle differenze nelle prestazioni è migliorata nel corso degli anni e ora il motivo principale per utilizzare alberi rosso-neri su AVL sarebbe non avere accesso a una buona implementazione AVL poiché sono leggermente meno comuni forse perché non sono coperti in CLRS.

Entrambi gli alberi sono ora considerati forme di alberi con equilibrio di rango, ma gli alberi rosso-neri sono costantemente più lenti di circa il 20% nei test del mondo reale . O addirittura del 30-40% più lento quando vengono inseriti dati sequenziali .

Quindi le persone che hanno studiato alberi rosso-neri ma non alberi AVL tendono a scegliere alberi rosso-neri. Gli usi principali degli alberi rosso-neri sono descritti in dettaglio nella voce di Wikipedia per loro .


1
Divertente! nella mia lettura, l'articolo di libavl sembra dire che AVL e RB sono testa a testa, e nessuno dei due è chiaramente migliore dell'altro in generale (quale sia il migliore dipende dal carico di lavoro). Non vedo da nessuna parte un'affermazione che AVL sia nel complesso circa il 20% più veloce.
Stefan

3

Altre risposte qui riassumono bene i pro ei contro degli alberi RB e AVL, ma ho trovato questa differenza particolarmente interessante:

Gli alberi AVL non supportano il costo di aggiornamento ammortizzato costante [ma gli alberi rosso-neri sì]

Fonte: Mehlhorn & Sanders (2008) (sezione 7.4)

Quindi, mentre entrambi gli alberi RB e AVL garantiscono O (log (N)) tempo peggiore per la ricerca, l'inserimento e l'eliminazione, il ripristino della proprietà AVL / RB dopo l' inserimento o l'eliminazione di un nodo può essere eseguito in O (1) tempo ammortizzato per alberi rosso-neri.


Credo che l'inserimento dell'albero AVL abbia lo stesso / simile costo ammortizzato ma produca un albero bilanciato meglio (1.44log (N) vs 2log (N)). Allo stesso tempo, l'eliminazione nella struttura ad albero AVL potrebbe richiedere più rotazioni. IMHO, questo è affrontato in WAVL en.wikipedia.org/wiki/WAVL_tree
Sergey Shandar

1

I programmatori generalmente non amano allocare dinamicamente la memoria. Il problema con l'albero avl è che per "n" elementi hai bisogno almeno di log2 (log2 (n)) ... (altezza-> log2 (n)) bit per memorizzare l'altezza dell'albero! Quindi, quando gestisci dati enormi, non puoi essere sicuro di quanti bit assegnare per memorizzare l'altezza in ogni nodo.

Ad esempio, se usi 4 byte int (32 bit) per memorizzare l'altezza. L'altezza massima può essere: 2 ^ 32 e quindi il numero massimo di elementi che puoi memorizzare nell'albero è 2 ^ (2 ^ 32) - (sembra essere molto grande ma in quest'era di dati niente è troppo grande immagino). E quindi se superi questo limite devi allocare dinamicamente più spazio per la memorizzazione dell'altezza.

Questa è una risposta suggerita da un professore della mia università che mi è sembrata ragionevole! Spero di avere un senso.

Modifiche: gli alberi AVL sono più bilanciati rispetto agli alberi neri rossi, ma possono causare più rotazioni durante l'inserimento e l'eliminazione. Quindi, se la tua applicazione prevede molti frequenti inserimenti ed eliminazioni, allora dovrebbero essere preferiti gli alberi Red Black. E se gli inserimenti e le eliminazioni sono meno frequenti e la ricerca è un'operazione più frequente, l'albero AVL dovrebbe essere preferito rispetto all'albero nero rosso. - Fonte GEEKSFORGEEKS.ORG


1
Direi che è interessante ma poco pratico. Mentre è vero che nel caso più compatto sarebbe un compito difficile scegliere il numero più efficiente di bit da allocare per l'altezza, in pratica qualsiasi spazio residuo inferiore a un byte sarà sicuramente inutilizzato e tutto ciò che rimane in uno spazio di 4 o anche 8 byte quasi certamente non verrà utilizzato. La memoria non viene allocata non allineata per motivi di prestazioni che annullano notevolmente il vantaggio di recuperare una piccola quantità di spazio. I puntatori ai figli e al valore occupano 24 byte; È improbabile che altri 8 abbiano alcun costo pratico.
Mumbleskates

4
you need need atleast log2(log2(n))...(height->log2(n)) bits to store the height of [an AVL] treeNon ho bisogno dell'altezza di alcun nodo in un albero AVL per implementarlo. Hai bisogno di un po ' di informazioni extra per ogni nodo ( I AM THE GREATEST (il fratello con il sottoalbero più alto))); è più conveniente oltre che convenzionale avere due bit extra (il bambino è più alto per sinistra e destra), come presentato da AV e L.
barba grigia

4
2 ^ (2 ^ 32) elementi è molto ... come se potessi immagazzinare ogni singola molecola nell'intero universo, e ogni possibile coppia di quelle molecole, e ogni possibile tripla, e ancora non inizi nemmeno ad avvicinarti nemmeno lontanamente a essendo all'interno di una piccola frazione di una piccola percentuale della radice cubica di quel numero diviso per cento quintilioni.
punto

4
Questo è molto fuorviante. Innanzitutto, non è necessario memorizzare l'altezza in un nodo di un albero AVL. In secondo luogo, anche se lo facessimo, e anche se la quantità tipica di memoria disponibile raddoppia ogni anno, abbiamo ancora 4 miliardi di anni prima che l'altezza dei nostri alberi superi quello che può essere memorizzato in 32 bit.
Gassa

3
2 ^ (2 ^ 32) oggetti è ridicolmente, follemente, assolutamente più di quanto qualsiasi computer che possiamo immaginare in questo momento possa mai contenere. Siamo a qualcosa come 2 ^ 40. Controlla di nuovo di fare matematica.
Stefan Reich

-1

Il riequilibrio dell'albero AVL dovrebbe soddisfare la proprietà seguente. (Riferimento Wiki - Albero AVL )

In un albero AVL, le altezze dei due sottoalberi figli di qualsiasi nodo differiscono al massimo di uno; se in qualsiasi momento differiscono di più di uno, viene effettuato un ribilanciamento per ripristinare questa proprietà.

Quindi questo implica che l'altezza complessiva dell'albero AVL non può impazzire, cioè le ricerche saranno migliori con gli alberi AVL. E poiché devono essere eseguite operazioni aggiuntive (rotazioni) per non far impazzire l'altezza, le operazioni di modifica dell'albero possono essere un po 'costose.


È menzionato in molti altri luoghi, ma il motivo per cui questa risposta non è molto buona è che gli alberi AVL e RB mantengono effettivamente vincoli estremamente simili: gli alberi RB non saranno più di 2,0 volte l'altezza richiesta e per gli alberi AVL quel fattore è circa 1,44. Di conseguenza, gli alberi AVL ruotano leggermente più spesso, ma il costo per rotazione è essenzialmente lo stesso; non è costoso.
Mumbleskates
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.