Implementazione della struttura dei dati immutabile (persistente) simile a matrice con indicizzazione rapida, aggiunta, anteposizione, iterazione


11

Sto cercando una struttura di dati persistente simile all'array (ma immutabile), che consenta operazioni veloci di indicizzazione, aggiunta, prepend e iterazione (buona località).

Clojure fornisce un vettore persistente, ma è solo per un'aggiunta veloce. Scala's Vector ha effettivamente un'appendice e prepend a tempo costante, ma non riesco a capire come sia implementata, poiché si basa sulla stessa struttura di dati (trie vettoriale bitmap) del vettore Clojure e, a quanto ho capito, trie vettoriale bitmap non può avere anteprime veloci senza alcuni trucchi.

Sono interessato non all'implementazione pronta per l'uso ma a una descrizione di come implementare una struttura di dati di questo tipo.

Risposte:


13

Il candidato ovvio è un albero binario equilibrato persistente . Tutte le operazioni che hai elencato possono essere eseguite in tempo o , usando la copia del percorso . Per maggiori dettagli su come ottenere questo tempo di esecuzione, consultare il libro di Chris Okasaki a cui si fa riferimento di seguito o la mia risposta qui .O ( lg n )O(1)O(lgn)

Naturalmente, come variante, ogni foglia di un tale albero potrebbe contenere essa stessa una matrice immutabile (una sequenza di valori consecutivi). Questo rende l'aggiornamento di un valore meno efficiente, ma potrebbe funzionare bene per la tua situazione, se non hai mai intenzione di modificare un valore esistente, basta aggiungere e anteporre. In questo modo, il tuo vettore è rappresentato come una sequenza di sequenze immutabili, rappresentato come un albero binario bilanciato con matrici immutabili nelle foglie. Ciò consente una rapida indicizzazione (logaritmico nel numero di foglie), una rapida aggiunta e prependuta e una rapida iterazione. La complessità asintotica nel caso peggiore non è migliore, ma le prestazioni in pratica potrebbero essere significativamente migliori.

Il riferimento standard è il libro di Chris Okasaki del 1998 "Strutture di dati puramente funzionali".
Guarda anche


Grazie. Sembra che gli alberi RRB siano buoni candidati e abbiano già implementato Clojure (non completo).
Tvaroh,

Immagino che Okasaki ci dica come ottenere questi runtime sotto immutabilità e persistenza?
Raffaello

1
@Raphael, yup. Ho aggiunto riferimenti per spiegare come si ottiene l'autonomia (all'inizio della mia risposta).
DW

4

Ho descritto un'implementazione di tale struttura di dati nel mio articolo sulla corrispondenza incrementale delle espressioni regolari - vedi http://jkff.info/articles/ire/#ropes-strings-with-fast-concatenation e il testo sotto e sopra quella sezione .

È una varietà di albero ad altezza costante (come alberi B o 2-3 alberi). Fondamentalmente si tratta di un albero (2,3), le cui foglie sono matrici (N, 2N-1), al fine di evitare il sovraccarico per elemento. (Una matrice (N, 2N-1) è una matrice le cui lunghezze sono comprese nell'intervallo N..2N-1.) Una N maggiore offre un overhead più piccolo ma aumenta linearmente la complessità della divisione e della concatenazione. Operazioni come indicizzazione, divisione e concatenazione sono molto simili al modo in cui lavorano in 2-3 alberi, generalizzando a (N, 2N-1) a livello fogliare.


Rottura dei collegamenti; si prega di fornire un riferimento adeguato e affidabile (che consenta alle persone di trovare il proprio documento senza il link).
Raffaello

Non ho pubblicato l'articolo su nessun giornale, solo sul mio sito web personale. Probabilmente dovrei metterlo su Arxiv, buona idea.
jkff,

Pensavo principalmente agli autori, al titolo e all'anno, il che semplifica Googling, se necessario. Metterlo su arXiv sarebbe ancora meglio, vero!
Raffaello
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.