In passato, nella classe delle strutture dati abbiamo imparato come funzionavano gli alberi AVL . Lo avrei avuto in una delle mie lezioni, ma l'istruttore ha detto "non lo userai mai realmente" e invece ci ha fatto imparare 2-3 alberi e b * alberi. Erano giorni in cui la memoria era stretta e i processi erano singolarmente sottoposti a thread. Non hai usato un deque quando un elenco collegato singolarmente avrebbe funzionato altrettanto bene.
L'elenco di salto è molto più comune oggi con più memoria disponibile e concorrenza che rappresentano un problema (non è necessario bloccare molto quando si agisce come scrittore in un elenco di salto, rispetto a tutto con un albero AVL).
Francamente, ora è la mia struttura di dati preferita in quanto è qualcosa che posso facilmente ragionare su come funziona sotto e dove sarà vantaggioso o svantaggioso da usare.
Non avrai bisogno di scriverne uno da zero (a meno che tu non lo ottenga come una domanda di intervista - ma allora hai la stessa probabilità di implementare un albero AVL).
Si sta andando ad avere bisogno di capire il motivo per cui si desidera selezionare un ConcurrentSkipListMap
in Java piuttosto che una HashMap
o TreeMap
o una qualsiasi delle altre implementazioni della mappa.
Per capire come funziona, devi capire come funziona un albero binario. Aspetta, lasciami modificare. Devi capire come funziona un albero binario bilanciato . Senza bilanciare un albero binario, non ottieni alcun vantaggio reale con la sua ricerca.
Diciamo che abbiamo questo albero:
E inseriamo un '8' in esso. Ora abbiamo:
E questo non è equilibrato. Quindi, andiamo a fare la magia di bilanciarlo tramite qualche implementazione ...
E hai di nuovo un albero equilibrato. Ma è stata molta magia che ho agitato la mano.
Consente di saltare un elenco.
Questo sembra essere idealizzato. Pochi lo sono, ma mostra la natura equilibrata dell'albero binario che l'ideale skiplist approssima.
Ora, vogliamo inserire un 6 lì dentro. Questo lo sta inserendo proprio come un elenco collegato. Tuttavia, iniziamo dall'alto e scendiamo. I primi punti a 5. È 6> 5? Sì. Ok, ora il top punta fino alla fine, quindi scendiamo in pila (siamo sul 5). Il prossimo è 7. È 6> 7? No. Quindi scendiamo di livello e siamo al livello base, quindi inseriamo 6 a destra del 5.
Lanciamo una moneta: teste che costruiamo, code che rimaniamo. Tails. Non è necessario fare altro.
Ora inseriamo 8. 8> 5? Sì. 8> 7? Sì. E ora siamo di nuovo al livello inferiore dopo aver seguito le frecce e lo stack intorno e testiamo 8> 11? No. Quindi inseriamo l'8 a destra del 7.
Lanciamo una moneta: teste che costruiamo, code che rimaniamo. Tails. Non è necessario fare altro.
Nell'albero bilanciato, ci saremmo tutti preoccupati che l'albero non fosse bilanciato ora. Ma questo non è un albero - è un elenco da saltare. Abbiamo approssimare un albero bilanciato.
Ora inseriamo un 10. Eviterò tutti i confronti.
Lanciamo una moneta: teste che costruiamo, code che rimaniamo. Teste! E capovolgi di nuovo, Heads di nuovo! Capovolgilo di nuovo, ok, c'è una coda. Due livelli sopra l'elenco collegato di base.
Il vantaggio qui è che ora se vogliamo inserire un 12, possiamo saltare da 5 a 10 senza fare tutti gli altri confronti. Possiamo ignorarli con l'elenco di salto. E non dobbiamo preoccuparci dell'albero bilanciato: la natura probabilistica dell'impilamento lo fa per noi.
Perché è così utile? Perché quando inserisco il 10 posso farlo bloccando la scrittura sui puntatori 5 e 7 e 8 piuttosto che sull'intera struttura. E mentre lo sto facendo, i lettori possono ancora passare attraverso l'elenco di salto senza avere uno stato incoerente. Per un utilizzo simultaneo, è più veloce non dover bloccare. Per iterare sul livello inferiore, è più veloce di un albero (le gioie degli algoritmi BFS e DFS per la navigazione dell'albero - non devi preoccuparti di loro).
Lo incontrerai? Probabilmente lo vedrai in uso in alcuni punti. E poi saprai perché l'autore ha scelto quella implementazione piuttosto che una TreeMap
o HashMap
per la struttura.
Gran parte di questo è stato preso in prestito dal mio post sul blog: The Skip List