La mia domanda è se la struttura dei dati di Trie e Radix Trie siano la stessa cosa?
In breve, no. La categoria Radix Trie descrive una particolare categoria di Trie , ma ciò non significa che tutti i tentativi siano radix.
Se non sono uguali, qual è il significato di Radix trie (aka Patricia Trie)?
Presumo che volevi scrivere non sono nella tua domanda, da qui la mia correzione.
Allo stesso modo, PATRICIA denota un tipo specifico di radix trie, ma non tutti i radix try sono PATRICIA.
Cos'è un trie?
"Trie" descrive una struttura di dati ad albero adatta per l'uso come array associativo, dove rami o bordi corrispondono a parti di una chiave. La definizione di parti è piuttosto vaga, qui, perché diverse implementazioni di try utilizzano diverse lunghezze di bit per corrispondere ai bordi. Ad esempio, un trie binario ha due lati per nodo che corrispondono a uno 0 o un 1, mentre un trie a 16 vie ha sedici lati per nodo che corrispondono a quattro bit (o una cifra esadecimale: da 0x0 a 0xf).
Questo diagramma, recuperato da Wikipedia, sembra rappresentare un trie con (almeno) le chiavi "A", "to", "tea", "ted", "ten" e "inn" inserite:
Se questo trie dovesse memorizzare elementi per le chiavi "t", "te", "i" o "in", ci sarebbe bisogno di informazioni aggiuntive presenti in ogni nodo per distinguere tra nodi nulli e nodi con valori effettivi.
Cos'è un radix trie?
"Radix trie" sembra descrivere una forma di trie che condensa parti di prefisso comuni, come Ivaylo Strandjev ha descritto nella sua risposta. Considera che un trie a 256 vie che indicizza i tasti "smile", "smiled", "smiles" e "smiling" utilizzando le seguenti assegnazioni statiche:
root['s']['m']['i']['l']['e']['\0'] = smile_item;
root['s']['m']['i']['l']['e']['d']['\0'] = smiled_item;
root['s']['m']['i']['l']['e']['s']['\0'] = smiles_item;
root['s']['m']['i']['l']['i']['n']['g']['\0'] = smiling_item;
Ogni pedice accede a un nodo interno. Ciò significa che per recuperare smile_item
, devi accedere a sette nodi. Otto accessi al nodo corrispondono a smiled_item
e smiles_item
e nove a smiling_item
. Per questi quattro elementi, ci sono quattordici nodi in totale. Tuttavia, hanno tutti i primi quattro byte (corrispondenti ai primi quattro nodi) in comune. Condensando quei quattro byte per creare un root
che corrisponde a ['s']['m']['i']['l']
, sono stati ottimizzati quattro accessi ai nodi. Ciò significa meno memoria e meno accessi ai nodi, il che è un'ottima indicazione. L'ottimizzazione può essere applicata in modo ricorsivo per ridurre la necessità di accedere a byte di suffisso non necessari. Alla fine, arrivi a un punto in cui stai solo confrontando le differenze tra la chiave di ricerca e le chiavi indicizzate nelle posizioni indicizzate dal trie. Questo è un trie radix.
root = smil_dummy;
root['e'] = smile_item;
root['e']['d'] = smiled_item;
root['e']['s'] = smiles_item;
root['i'] = smiling_item;
Per recuperare gli elementi, ogni nodo necessita di una posizione. Con una chiave di ricerca di "sorrisi" e una root.position
di 4, accediamo root["smiles"[4]]
, che sembra essere root['e']
. Lo memorizziamo in una variabile chiamata current
. current.position
è 5, che è la posizione della differenza tra "smiled"
e "smiles"
, quindi il prossimo accesso sarà root["smiles"[5]]
. Questo ci porta a smiles_item
, e alla fine della nostra stringa. La nostra ricerca è terminata e l'elemento è stato recuperato, con solo tre accessi al nodo invece di otto.
Cos'è un trie PATRICIA?
Un trie PATRICIA è una variante dei tentativi radix per i quali dovrebbero esserci solo n
nodi usati per contenere n
oggetti. Nel nostro grossolanamente dimostrato radice trie pseudocodice sopra, ci sono cinque nodi complessivamente: root
(che è un nodo nullaria, contiene alcun valore effettivo), root['e']
, root['e']['d']
, root['e']['s']
e root['i']
. In un trie PATRICIA ce ne dovrebbero essere solo quattro. Diamo un'occhiata a come questi prefissi potrebbero differire guardandoli in binario, poiché PATRICIA è un algoritmo binario.
smile: 0111 0011 0110 1101 0110 1001 0110 1100 0110 0101 0000 0000 0000 0000
smiled: 0111 0011 0110 1101 0110 1001 0110 1100 0110 0101 0110 0100 0000 0000
smiles: 0111 0011 0110 1101 0110 1001 0110 1100 0110 0101 0111 0011 0000 0000
smiling: 0111 0011 0110 1101 0110 1001 0110 1100 0110 1001 0110 1110 0110 0111 ...
Consideriamo che i nodi vengono aggiunti nell'ordine in cui sono presentati sopra. smile_item
è la radice di questo albero. La differenza, evidenziata in grassetto per renderla leggermente più facile da individuare, è nell'ultimo byte di "smile"
, al bit 36. Fino a questo punto, tutti i nostri nodi hanno lo stesso prefisso. smiled_node
appartiene a smile_node[0]
. La differenza tra "smiled"
e si "smiles"
verifica al bit 43, dove "smiles"
ha un bit "1", così smiled_node[1]
è smiles_node
.
Invece di utilizzare NULL
come rami e / o informazioni interne supplementari per indicare quando una ricerca termina, i rami collegano indietro fino al qualche albero, quindi una ricerca termina quando l'offset di prova diminuisce invece di aumentare. Ecco un semplice diagramma di un tale albero (sebbene PATRICIA sia davvero più un grafico ciclico, che un albero, come vedrai), che è stato incluso nel libro di Sedgewick menzionato di seguito:
È possibile un algoritmo PATRICIA più complesso che coinvolge chiavi di lunghezza variante, sebbene alcune delle proprietà tecniche di PATRICIA vengano perse nel processo (vale a dire che ogni nodo contiene un prefisso comune con il nodo precedente):
Diramando in questo modo, ci sono una serie di vantaggi: Ogni nodo contiene un valore. Ciò include la radice. Di conseguenza, la lunghezza e la complessità del codice diventano molto più brevi e probabilmente un po 'più veloci nella realtà. Almeno un ramo e al massimo k
rami (dove k
è il numero di bit nella chiave di ricerca) vengono seguiti per individuare un elemento. I nodi sono piccoli , perché memorizzano solo due rami ciascuno, il che li rende abbastanza adatti per l'ottimizzazione della località della cache. Queste proprietà fanno di PATRICIA il mio algoritmo preferito finora ...
Taglierò questa descrizione qui breve, al fine di ridurre la gravità della mia imminente artrite, ma se vuoi saperne di più su PATRICIA puoi consultare libri come "The Art of Computer Programming, Volume 3" di Donald Knuth , o uno qualsiasi degli "Algoritmi in {la tua lingua preferita}, parti 1-4" di Sedgewick.
radix-tree
piuttosto cheradix-trie
? Inoltre, ci sono alcune domande contrassegnate con esso.