Meine Frage ist, ob Trie- Datenstruktur und Radix Trie dasselbe sind.
Kurz gesagt, nein. Die Kategorie Radix Trie beschreibt eine bestimmte Kategorie von Trie , aber das bedeutet nicht, dass alle Versuche Radix-Versuche sind.
Wenn sie [nicht] gleich sind, was bedeutet dann Radix Trie (auch bekannt als Patricia Trie)?
Ich nehme an, Sie wollten schreiben, sind nicht in Ihrer Frage, daher meine Korrektur.
In ähnlicher Weise bezeichnet PATRICIA einen bestimmten Typ von Radix-Versuchen, aber nicht alle Radix-Versuche sind PATRICIA-Versuche.
Was ist ein Versuch?
"Trie" beschreibt eine Baumdatenstruktur, die zur Verwendung als assoziatives Array geeignet ist, wobei Zweige oder Kanten Teilen eines Schlüssels entsprechen. Die Definition von Teilen ist hier ziemlich vage, da unterschiedliche Implementierungen von Versuchen unterschiedliche Bitlängen verwenden, um Kanten zu entsprechen. Beispielsweise hat ein binärer Versuch zwei Kanten pro Knoten, die einer 0 oder einer 1 entsprechen, während ein 16-Wege-Versuch sechzehn Kanten pro Knoten hat, die vier Bits entsprechen (oder eine hexadezimale Ziffer: 0x0 bis 0xf).
Dieses aus Wikipedia abgerufene Diagramm scheint einen Versuch mit (mindestens) den eingefügten Schlüsseln 'A', 'bis', 'Tee', 'Ted', 'Zehn' und 'Gasthaus' darzustellen:
Wenn dieser Versuch Elemente für die Schlüssel 't', 'te', 'i' oder 'in' speichern würde, müssten an jedem Knoten zusätzliche Informationen vorhanden sein, um zwischen Nullknoten und Knoten mit tatsächlichen Werten zu unterscheiden.
Was ist ein Radix Trie?
"Radix trie" scheint eine Form von trie zu beschreiben, die gemeinsame Präfixteile verdichtet, wie Ivaylo Strandjev in seiner Antwort beschrieben hat. Betrachten Sie einen 256-Wege-Versuch, der die Tasten "Lächeln", "Lächeln", "Lächeln" und "Lächeln" mit den folgenden statischen Zuweisungen indiziert:
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;
Jeder Index greift auf einen internen Knoten zu. Das heißt, um abzurufen smile_item
, müssen Sie auf sieben Knoten zugreifen. Acht Knotenzugriffe entsprechen smiled_item
und smiles_item
und neun smiling_item
. Für diese vier Elemente gibt es insgesamt vierzehn Knoten. Sie alle haben jedoch die ersten vier Bytes (entsprechend den ersten vier Knoten) gemeinsam. Durch die Verdichtung dieser vier Bytes zu einem root
entsprechenden Byte ['s']['m']['i']['l']
wurden vier Knotenzugriffe optimiert. Das bedeutet weniger Speicher und weniger Knotenzugriffe, was ein sehr guter Hinweis ist. Die Optimierung kann rekursiv angewendet werden, um den Zugriff auf unnötige Suffixbytes zu reduzieren. Schließlich kommen Sie zu einem Punkt, an dem Sie nur die Unterschiede zwischen dem Suchschlüssel und den indizierten Schlüsseln an den vom Versuch indizierten Stellen vergleichen. Dies ist ein Radix-Versuch.
root = smil_dummy;
root['e'] = smile_item;
root['e']['d'] = smiled_item;
root['e']['s'] = smiles_item;
root['i'] = smiling_item;
Zum Abrufen von Elementen benötigt jeder Knoten eine Position. Mit einem Suchschlüssel von "Lächeln" und einem root.position
von 4 greifen wir zu root["smiles"[4]]
, was zufällig ist root['e']
. Wir speichern dies in einer Variablen namens current
. current.position
ist 5, was der Ort der Differenz zwischen "smiled"
und ist "smiles"
, also wird der nächste Zugriff sein root["smiles"[5]]
. Dies bringt uns zum smiles_item
Ende unserer Saite. Unsere Suche wurde beendet und der Artikel wurde mit nur drei statt acht Knotenzugriffen abgerufen.
Was ist ein PATRICIA-Versuch?
Ein PATRICIA-Versuch ist eine Variante von Radix-Versuchen, für die immer nur n
Knoten verwendet werden sollten, die n
Elemente enthalten . In unserem primitiv demonstriert radix Trie Pseudocode oben, gibt es fünf Knoten in Summe: root
(die eine nullary Knoten ist, es enthält keinen Ist - Wert), root['e']
, root['e']['d']
, root['e']['s']
und root['i']
. In einem PATRICIA-Versuch sollten es nur vier sein. Schauen wir uns an, wie sich diese Präfixe unterscheiden können, indem wir sie binär betrachten, da PATRICIA ein binärer Algorithmus ist.
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 ...
Nehmen wir an, dass die Knoten in der oben angegebenen Reihenfolge hinzugefügt werden. smile_item
ist die Wurzel dieses Baumes. Der Unterschied, der fett gedruckt ist, um das Erkennen etwas zu erleichtern, liegt im letzten Byte von "smile"
Bit 36. Bis zu diesem Punkt haben alle unsere Knoten das gleiche Präfix. smiled_node
gehört zu smile_node[0]
. Der Unterschied zwischen "smiled"
und "smiles"
tritt bei Bit 43 auf, wo "smiles"
es ein '1'-Bit smiled_node[1]
gibt smiles_node
.
Anstatt mit NULL
als Zweig und / oder zusätzliche interne Informationen zu bezeichnen , wenn eine Suche beendet, die Zweige zurück Link auf den Baum irgendwo, so dass eine Suche beendet , wenn der zu Test Offset verringert statt erhöht. Hier ist ein einfaches Diagramm eines solchen Baums (obwohl PATRICIA, wie Sie sehen werden, eher ein zyklischer Graph als ein Baum ist), das in Sedgewicks unten erwähntem Buch enthalten war:
Ein komplexerer PATRICIA-Algorithmus mit Schlüsseln unterschiedlicher Länge ist möglich, obwohl einige der technischen Eigenschaften von PATRICIA dabei verloren gehen (nämlich, dass jeder Knoten ein gemeinsames Präfix mit dem Knoten davor enthält):
Eine solche Verzweigung bietet eine Reihe von Vorteilen: Jeder Knoten enthält einen Wert. Das schließt die Wurzel ein. Infolgedessen wird die Länge und Komplexität des Codes viel kürzer und in der Realität wahrscheinlich etwas schneller. Mindestens ein Zweig und höchstens k
Zweige (wobei k
die Anzahl der Bits im Suchschlüssel angegeben ist) werden befolgt, um ein Element zu lokalisieren. Die Knoten sind winzig , da sie jeweils nur zwei Zweige speichern, was sie für die Optimierung der Cache-Lokalität ziemlich geeignet macht. Diese Eigenschaften machen PATRICIA zu meinem bisherigen Lieblingsalgorithmus ...
Ich werde diese Beschreibung hier kurz fassen, um die Schwere meiner bevorstehenden Arthritis zu verringern. Wenn Sie jedoch mehr über PATRICIA erfahren möchten, können Sie Bücher wie "Die Kunst der Computerprogrammierung, Band 3" von Donald Knuth konsultieren oder einer der "Algorithmen in {Ihrer Lieblingssprache}, Teile 1-4" von Sedgewick.
radix-tree
eher als istradix-trie
? Darüber hinaus sind einige Fragen damit verbunden.