Quali sono i vantaggi di alberi binari di ricerca oltre tabelle hash?
Le tabelle hash può cercare qualsiasi elemento nel Theta (1) tempo ed è altrettanto facile per aggiungere un elemento .... ma non sono sicuro dei vantaggi che vanno al contrario.
Quali sono i vantaggi di alberi binari di ricerca oltre tabelle hash?
Le tabelle hash può cercare qualsiasi elemento nel Theta (1) tempo ed è altrettanto facile per aggiungere un elemento .... ma non sono sicuro dei vantaggi che vanno al contrario.
Una "vantaggio" di un albero binario è che può essere attraversato per elencare fuori tutti gli elementi in ordine. Questo non è possibile con una tabella hash, ma non è un normale funzionamento un disegno in una struttura hash.
Una tabella hash si occupano più spazio quando viene creato - avrà slot disponibili per gli elementi che devono ancora essere inseriti (anche se non sono mai inseriti), un albero binario di ricerca sarà solo grande come ha bisogno di essere. Inoltre, quando un hash-table ha bisogno di più spazio, espandendo ad un'altra struttura potrebbe richiedere molto tempo, ma che potrebbe dipendere l'attuazione.
Ricordate che Binary Search Trees (di riferimento-based) sono la memoria-efficiente. Essi non riservano più memoria di cui hanno bisogno per.
Ad esempio, se una funzione hash ha una gamma R(h) = 0...100, allora è necessario allocare una matrice di elementi 100 (puntatori-a), anche se sono solo hashing 20 elementi. Se si sceglie di usare un albero binario di ricerca per memorizzare le stesse informazioni, si potrebbe allocare solo tanto spazio quanto il necessario, così come alcuni metadati relativi collegamenti.
Un albero binario è più lento di cercare e inserire, ma ha la caratteristica molto piacevole di attraversamento infisso che significa in sostanza che si possono scorrere i nodi dell'albero in un modo ordinato.
Scorrendo le voci di una tabella hash semplicemente non ha molto senso, perché sono tutti sparsi in memoria.
Un albero binario di ricerca può essere implementato con una persistenza di interfaccia, in cui un nuovo albero viene restituito, ma il vecchio albero continua ad esistere. Implementato con attenzione, le quote di alberi vecchi e nuovi la maggior parte dei loro nodi. Non si può fare questo con una tabella di hash standard.
I principali vantaggi di un albero binario su una tabella di hash è che l'albero binario ti dà due operazioni aggiuntive non si può fare (facilmente, rapidamente) con una tabella hash
trovare l'elemento più vicino (non necessariamente uguale a) un valore arbitrario chiave (o vicini sopra / sotto)
scorrere i contenuti della struttura in modo ordinato
I due sono collegati - l'albero binario mantiene il suo contenuto in un modo ordinato, quindi le cose che richiedono che modo ordinato sono facili da fare.
A (bilanciato) albero binario di ricerca ha anche il vantaggio che la sua complessità asintotica è in realtà un limite superiore, mentre i tempi di "costante" per le tabelle hash sono volte ammortizzato: Se si dispone di una funzione di hash non idonei, si potrebbe finire degradante per tempo lineare , piuttosto che costante.
Se si desidera accedere ai dati in maniera ordinata, quindi una lista ordinata deve essere mantenuta in parallelo alla tabella hash. Un buon esempio è dizionario in .NET. (vedi http://msdn.microsoft.com/en-us/library/3fcwy8h6.aspx ).
Questo ha l'effetto collaterale di inserti non solo rallentamento, ma consuma una grande quantità di memoria di un b-albero.
Inoltre, dal momento che un b-albero è ordinato, è semplice da trovare intervalli di risultati, o per eseguire sindacati o unioni.
In aggiunta a tutti gli altri buoni commenti:
Le tabelle hash, in generale, hanno un migliore comportamento della cache che richiede meno memoria letture rispetto ad un albero binario. Per una tabella di hash che normalmente incorrere in una sola lettura prima di avere accesso a un riferimento di tenuta dei dati. L'albero binario, se è una variante equilibrato, richiede qualcosa nell'ordine di k * lg (n) letture di memoria per qualche costante k.
D'altra parte, se un nemico conosce il vostro hash-function il nemico può far valere la vostra tabella di hash per rendere le collisioni, ostacolando notevolmente le sue prestazioni. La soluzione è quello di scegliere l'hash-function a caso da una famiglia, ma un BST non ha questo svantaggio. Inoltre, quando la pressione tabella hash cresce troppo, spesso si tende a enlargen e riallocare la tabella di hash che può essere un'operazione costosa. La BST ha un comportamento più semplice qui e non tende a allocare improvvisamente un sacco di dati e di fare un'operazione di rimaneggiamento.
Gli alberi tendono ad essere l'ultima struttura di media dei dati. Essi possono agire come liste, può essere facilmente dividere per il funzionamento in parallelo, hanno veloce rimozione, inserimento e ricerca dell'ordine di O (lg n) . Essi non fare nulla particolarmente bene, ma non hanno alcun comportamento eccessivamente male.
Infine, BST sono molto più facili da implementare in (puri) linguaggi funzionali rispetto ai hash-tabelle e non richiedono aggiornamenti distruttivi da attuare (la persistenza degli argomenti da Pascal sopra).
vantaggio principale di tabella di hash è che lo fa quasi tutti i ops in ~ = O (1). Ed è molto facile da capire e implementare. Lo fa risolvere molti problemi "intervista" in modo efficiente. Quindi, se volete per rompere un colloquio di codifica, fare migliori amici con la tabella di hash ;-)
BST offrono anche il "findPredecessor" e le operazioni "findSuccessor" (per trovare gli elementi più piccoli e più grandi prossimo prossimi) a O (log n) tempo, che potrebbe anche essere operazioni molto a portata di mano. Hash Table non può fornire in quel tempo l'efficienza.
Dipende anche l'uso, Hash permette di localizzare corrispondenza esatta. Se si desidera eseguire una query per una gamma allora BST è la scelta. Supponiamo di avere un sacco di e1 dati, E2, E3 ..... it.
Con tabella hash è possibile individuare alcun elemento in tempo costante.
Se si vuole trovare valori di range maggiore di E41 e meno di E8, BST può trovare rapidamente quello.
La cosa fondamentale è la funzione hash utilizzato per evitare una collisione. Naturalmente, non possiamo assolutamente evitare una collisione, nel qual caso si ricorre al concatenamento o altri metodi. Questo rende il recupero non è più costante di tempo nel peggiore dei casi.
Una volta pieno, tabella hash deve aumentare le sue dimensioni secchio e copiare tutti gli elementi di nuovo. Questo è un costo aggiuntivo non presente su BST.
Un vantaggio che nessun altro ha fatto notare è che albero binario di ricerca consente di effettuare ricerche in modo efficiente gamma.
Al fine di illustrare la mia idea, voglio fare un caso estremo. Dire che si desidera ottenere tutti gli elementi le cui chiavi sono tra 0 e 5000. E in realtà c'è solo un tale elemento e 10000 altri elementi le cui chiavi non sono nel range. BST può fare ricerche gamma molto efficiente in quanto non cerca una sottostruttura che è impossibile avere la risposta.
Mentre, come si può fare ricerche gamma in una tabella hash? Si sia bisogno di iterare ogni spazio della benna, che è O (n), o se si deve guardare per se ciascuno di 1,2,3,4 ... fino a 5000 esiste. (Per quanto riguarda i tasti compresi tra 0 e 5000 sono un insieme infinito? Per esempio i tasti possono essere decimali)
Una tabella hash è una struttura dati non ordinata, Durante la progettazione di un telefono cellulare, si desidera mantenere quanti più dati possibile a disposizione per l'archiviazione dei dati. Una tabella hash è una struttura di dati non ordinato - il che significa che non mantiene gli elementi in un ordine particolare. Quindi, se si utilizza una tabella di hash per un rubrica del telefono cellulare, allora si avrebbe bisogno di memoria aggiuntiva per ordinare i valori in quanto si avrebbe sicuramente bisogno di visualizzare i valori in ordine alfabetico - si tratta di una rubrica, dopo tutto. Quindi, utilizzando una tabella di hash è necessario mettere da parte la memoria di ordinare gli elementi che sarebbero altrimenti essere utilizzato come spazio di archiviazione. Ma albero binario di ricerca è un dati ordinati structure.Because un albero binario di ricerca è già ordinato, non ci sarà alcun bisogno di sprecare memoria o tempo di elaborazione ordinano i record in un telefono cellulare. Come abbiamo accennato in precedenza, facendo una ricerca o di un inserto su un albero binario è più lento di farlo con una tabella di hash, ma un libro di indirizzo telefono cellulare sarà quasi mai avere più di 5.000 voci. Con un piccolo numero di voci quali, o di un albero binario di ricerca (log (n)) sarà sicuramente abbastanza veloce. Quindi, dato tutte queste informazioni, un albero binario di ricerca è la struttura dei dati che si dovrebbe utilizzare in questo scenario, dal momento che è una scelta migliore di una tabella di hash.
Le tabelle hash non sono buone per l'indicizzazione. Quando si è alla ricerca di un intervallo, i BST sono migliori. Questo è il motivo per cui la maggior parte degli indici di database utilizzano alberi B +, invece di Hash Tables
Dal Cracking Intervista Coding, 6a edizione
Siamo in grado di attuare la tabella hash con un albero binario di ricerca bilanciato (BST). Questo ci dà un O (log n) Occhiata tempo. Il vantaggio di questo è potenzialmente utilizza meno spazio, poiché allochiamo più un grande array. Possiamo anche scorrere le chiavi in ordine, che può essere utile a volte.
Le classi HashSet e da tavola sono raccolte non ordinate. Non è ovvio dall'interfaccia (e poteva essere altrimenti), ma le tabelle hash sono state implementate utilizzando AVL alberi. Ciò significa che il codice hash non viene ridotto il modulo di un array (meno collisioni) e significa anche che non v'è alcun rimaneggiamento di un array da fare (performance fluida). Il fatto che essi sono collezioni non ordinate significa che si fornisce solo una funzione e una funzione hashCode uguale - non un operatore di confronto pieno come per gli alberi. Quindi, se si utilizza una tabella tabella hash <K, T> o un albero binario albero <K, T> dipende dalla classe K - se è del tutto comparabile o solo l'uguaglianza comparabili.
Ci sono occasioni in cui il tipo di dati è sia comparabile e uguaglianza comparabili - come stringa. Ciò significa che HashSet <String> e impostare <String> sono possibili. Ricerche su un set hash di stringhe tendono ad essere circa 10 volte più veloce di ricerche su una serie ordinata di stringhe. Se il comparatore è costoso di alberi rallentare rispetto al hashtables. Se il comparatore è veloce, (come per gli interi e galleggianti), poi gli alberi saranno più veloci rispetto alle tabelle hash.
Un hashmap è un array associativo set. Quindi, la matrice di valori di input viene riunito in secchi. In uno schema di indirizzamento aperto, si dispone di un puntatore a un secchio, e ogni volta che si aggiunge un nuovo valore in un secchio, è scoprire dove nel secchio ci sono spazi liberi. Ci sono alcuni modi per fare questo- si avvia all'inizio del secchio e incrementare il puntatore ogni volta e verificare se il suo occupato. Questo si chiama scansione lineare. Quindi, si può fare una ricerca binaria come add, dove il doppio della differenza tra l'inizio del secchio e dove il doppio verso l'alto o verso il basso ogni volta che siete alla ricerca di uno spazio libero. Questo si chiama quadratica sondaggio. OK. Ora i problemi in entrambi questi metodi è che se il secchio trabocca nei prossimi secchi indirizzo, quindi è necessario to-
OK. ma se si utilizza un LinkedList non ci dovrebbe essere un problema giusto? Sì, in liste collegate non si dispone di questo problema. Considerando ciascun segmento per iniziare con una lista collegata, e se si dispone di 100 elementi in un secchio si richiede di attraversare quei 100 elementi per raggiungere la fine della LinkedList quindi la List.add (elemento E) richiederà tempo to
Il vantaggio della implementazione LinkedList è che non è necessario l'operazione di allocazione di memoria e O (N) trasferimento / copia di tutti i secchi, come nel caso della realizzazione di indirizzamento aperto.
Quindi, il modo per ridurre al minimo l'operazione O (N) è quello di convertire l'implementazione a quella di un Binary Search albero dove trovare le operazioni sono O (log (N)) e si aggiunge l'elemento nella sua posizione sulla base il suo valore. La caratteristica aggiunta di un BST è che viene risolto!
Alberi binari di ricerca sono buona scelta per implementare dizionario se i tasti hanno un qualche ordine totale (chiavi sono confrontabili) definita su di loro e si desidera conservare le informazioni di ordine.
Come BST conserva informazioni di ordine, vi fornisce quattro ulteriori operazioni di set dinamico che non possono essere eseguite (efficiente) utilizzando le tabelle hash. Queste operazioni sono:
Tutte queste operazioni, come ogni operazione BST hanno tempo la complessità di O (H). Inoltre, tutte le chiavi memorizzate rimangono ordinati nel BST permettendo così di ottenere la sequenza ordinata delle chiavi solo attraversando l'albero in in-ordine.
In sintesi, se invece si è operazioni di inserimento, cancellare e rimuovere poi tabella di hash è imbattibile (la maggior parte del tempo) in termini di prestazioni. Ma se volete qualsiasi o tutte le operazioni sopra elencate è necessario utilizzare un BST, preferibilmente un BST auto-bilanciamento.
Alberi binari di ricerca può essere più veloce quando viene utilizzato con chiavi stringa. Soprattutto quando le stringhe sono lunghe.
Alberi binari di ricerca utilizzando i confronti per meno / più grande, che sono veloci per le stringhe (quando non sono uguali). Quindi un BST può rispondere rapidamente quando non viene trovata una stringa. Quando è trovata avrà bisogno di fare un solo confronto pieno.
In una tabella hash. È necessario calcolare l'hash della stringa e questo significa che è necessario passare attraverso tutti i byte almeno una volta per calcolare l'hash. Poi di nuovo, quando viene trovata una voce corrispondente.