2013-07-17 16 views
10

Sono disposto ad utilizzare una struttura dati come buffer di overflow di spazio costante. Voglio avere un inserto efficiente ma soprattutto una rimozione efficiente dell'elemento min. Stavo pensando di utilizzare un heap dal momento che ho O (log (n)) find_min() e log (n) inserimento e cancellazione. D'altra parte so che non capisco il vantaggio rispetto ad un albero rosso-nero visto che ha anche O (log (n)) insert e delete ma e O (1) find min/max. E il vantaggio dell'output ordinato (non mi interessa).Mucchio o albero rosso-nero?

La domanda è legata a: Is a red-black tree my ideal data structure?

Dal momento che ho entrambe le strutture disponibili da std :: map e da boost :: mucchio perché dovrei preferire usare mucchio anziché l'albero rosso-nero? Infine, usando l'albero rosso-nero ho anche O (log (n)) tempo di ricerca per una voce mentre per un heap il tempo è O (n) che è importante poiché i duplicati esistono.

+1

Considerare un buffer circolare. Non so se è appropriato per i tuoi usi. –

+0

possibile duplicato di [Heap vs Binary Search Tree (BST)] (http://stackoverflow.com/questions/6147242/heap-vs-binary-search-tree-bst) –

risposta

14

La differenza riguarda principalmente le modalità di utilizzo delle strutture.

  • cumuli binari sono strutture di dati molto veloci per inserire valori e recuperare il valore minimo. Tuttavia, non supportano la ricerca efficiente o la cancellazione di valori casuali.

  • Gli alberi rossi/neri sono alberi di ricerca binari bilanciati che supportano l'inserimento efficiente, la cancellazione, la ricerca di valori arbitrari e (ragionevolmente veloce) la ricerca-minima. Tuttavia, hanno un sovraccarico rispetto a un heap binario.

Se tutto ciò che serve è l'inserimento, find-minimo, e rimuovere-minima, l'heap binario è probabilmente una scelta superiore, perché il sovraccarico è inferiore e il tempo di esecuzione dovrebbe essere più veloce. Se è necessario inserire e rimuovere valori arbitrari o cercare valori arbitrari, l'albero rosso/nero è probabilmente la scelta migliore. Come per tutti gli aspetti ingegneristici, la scelta della struttura dei dati corretta è incentrata sui compromessi.

Inoltre, si noti che è possibile utilizzare std::priority_queue se è necessario un heap binario; non è necessario utilizzare Boost. Non è inoltre garantito che std::map sia un albero rosso/nero; è probabilmente una sorta di BST bilanciato, ma potrebbe essere bilanciato usando qualche altro algoritmo.

Spero che questo aiuti!

+0

Grazie per la rapida risposta. Nei miei dati ho duplicati quindi non posso evitare find() che è costoso su un heap. D'altra parte l'inserimento e la cancellazione sono più veloci in un heap ma logaritmici nell'albero rosso-nero. Immagino che l'albero rosso-nero sia la risposta giusta per questo. Tuttavia, ho visto in un foglio che usa un mucchio anche se hanno operazioni di find() e questo è il motivo per cui sono confuso. – nikosdi

+3

Un heap non è una struttura di dati di ricerca; è possibile, tuttavia, memorizzare la posizione di un elemento all'interno dell'heap, quindi in un secondo momento è possibile modificare la sua priorità (che sposta l'elemento verso l'alto o verso il basso di conseguenza). Molti algoritmi geometrici basati su sweep-line richiedono questo tipo di "ricerca e aggiornamento". – DanielKO

2

Un heap è facilmente implementabile nella memoria contigua, cioè una matrice. Un albero rosso-nero viene in genere costruito con un'allocazione heap separata per ogni nodo. L'albero rosso-nero finisce per accedere alla memoria su tutto l'heap per ogni attraversamento dell'albero. Questo è il comportamento della cache nel caso peggiore. Anche se la complessità algoritmica di alcune operazioni è la stessa per entrambe le strutture, l'overhead costante per l'albero rosso-nero è molto più alto.