Verwendung der Vorbestellungs-, In-Order- und Nachbestellungs-Traversal-Strategie
Bevor Sie verstehen können, unter welchen Umständen Vorbestellung, Reihenfolge und Nachbestellung für einen Binärbaum verwendet werden müssen, müssen Sie genau verstehen, wie jede Durchquerungsstrategie funktioniert. Verwenden Sie den folgenden Baum als Beispiel.
Die Wurzel des Baums ist 7 , der Knoten ganz links ist 0 , der Knoten ganz rechts ist 10 .
Durchlauf vorbestellen :
Zusammenfassung: Beginnt an der Wurzel ( 7 ) und endet am äußersten rechten Knoten ( 10 )
Durchlaufsequenz: 7, 1, 0, 3, 2, 5, 4, 6, 9, 8, 10
In-Order-Traversal :
Zusammenfassung: Beginnt am äußersten linken Knoten ( 0 ) und endet am äußersten rechten Knoten ( 10 )
Durchlaufsequenz: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
Nachbestellungsdurchlauf :
Zusammenfassung: Beginnt mit dem Knoten ganz links ( 0 ) und endet mit der Wurzel ( 7 )
Durchlaufsequenz: 0, 2, 4, 6, 5, 3, 1, 8, 10, 9, 7
Wann ist Pre-Order, In-Order oder Post-Order zu verwenden?
Die vom Programmierer ausgewählte Durchlaufstrategie hängt von den spezifischen Anforderungen des zu entwerfenden Algorithmus ab. Das Ziel ist die Geschwindigkeit. Wählen Sie also die Strategie, mit der Sie die Knoten erhalten, die Sie am schnellsten benötigen.
Wenn Sie wissen, dass Sie die Wurzeln erforschen müssen, bevor Sie Blätter untersuchen, wählen Sie eine Vorbestellung, da Sie vor allen Blättern auf alle Wurzeln stoßen.
Wenn Sie wissen, dass Sie alle Blätter vor Knoten untersuchen müssen, wählen Sie Nachbestellung , da Sie keine Zeit damit verschwenden, Wurzeln bei der Suche nach Blättern zu untersuchen.
Wenn Sie wissen, dass der Baum eine inhärente Sequenz in den Knoten hat und Sie den Baum wieder in seine ursprüngliche Sequenz reduzieren möchten, sollte eine Durchquerung in der richtigen Reihenfolge verwendet werden. Der Baum würde auf die gleiche Weise abgeflacht, wie er erstellt wurde. Bei einem Durchlauf vor oder nach der Bestellung wird der Baum möglicherweise nicht in die Reihenfolge zurückgespult, in der er erstellt wurde.
Rekursive Algorithmen für Pre-Order, In-Order und Post-Order (C ++):
struct Node{
int data;
Node *left, *right;
};
void preOrderPrint(Node *root)
{
print(root->name); //record root
if (root->left != NULL) preOrderPrint(root->left); //traverse left if exists
if (root->right != NULL) preOrderPrint(root->right);//traverse right if exists
}
void inOrderPrint(Node *root)
{
if (root.left != NULL) inOrderPrint(root->left); //traverse left if exists
print(root->name); //record root
if (root.right != NULL) inOrderPrint(root->right); //traverse right if exists
}
void postOrderPrint(Node *root)
{
if (root->left != NULL) postOrderPrint(root->left); //traverse left if exists
if (root->right != NULL) postOrderPrint(root->right);//traverse right if exists
print(root->name); //record root
}
Vorbestellung: Zum Erstellen einer Kopie eines Baums. Wenn Sie beispielsweise eine Replik eines Baums erstellen möchten, platzieren Sie die Knoten in einem Array mit einer Vorbestellungsdurchquerung. Führen Sie dann für jeden Wert im Array einen Einfügevorgang für einen neuen Baum aus. Am Ende erhalten Sie eine Kopie Ihres ursprünglichen Baums.
In der Reihenfolge :: Wird verwendet, um die Werte der Knoten in einer BST in nicht abnehmender Reihenfolge abzurufen.
Post-Bestellung: : Gebrauchte einen Baum von Blatt zu root löschen
quelle
Wenn ich einfach das hierarchische Format des Baums in einem linearen Format ausdrucken möchte, würde ich wahrscheinlich die Vorbestellungsdurchquerung verwenden. Beispielsweise:
quelle
TreeView
Komponente in einer GUI-Anwendung.Vor- und Nachbestellung beziehen sich auf rekursive Top-Down- bzw. Bottom-Up-Algorithmen. Wenn Sie einen bestimmten rekursiven Algorithmus iterativ auf Binärbäume schreiben möchten, tun Sie dies im Wesentlichen.
Beachten Sie außerdem, dass Sequenzen vor und nach der Bestellung zusammen den vorliegenden Baum vollständig spezifizieren und eine kompakte Codierung ergeben (zumindest für spärliche Bäume).
quelle
Es gibt unzählige Orte, an denen dieser Unterschied eine echte Rolle spielt.
Eine großartige, auf die ich hinweisen werde, ist die Codegenerierung für einen Compiler. Betrachten Sie die Aussage:
Die Art und Weise, wie Sie Code dafür generieren würden, besteht (natürlich naiv) darin, zuerst Code zum Laden von y in ein Register, zum Laden von 32 in ein Register und dann zum Generieren einer Anweisung zum Hinzufügen der beiden zu generieren. Da sich etwas in einem Register befinden muss, bevor Sie es manipulieren (nehmen wir an, Sie können immer konstante Operanden ausführen, aber was auch immer), müssen Sie dies auf diese Weise tun.
Im Allgemeinen reduzieren sich die Antworten auf diese Frage im Wesentlichen darauf: Der Unterschied ist wirklich wichtig, wenn eine gewisse Abhängigkeit zwischen der Verarbeitung verschiedener Teile der Datenstruktur besteht. Sie sehen dies beim Drucken der Elemente, beim Generieren von Code (der externe Status macht den Unterschied, Sie können dies natürlich auch monadisch anzeigen) oder wenn Sie andere Arten von Berechnungen über die Struktur durchführen, die Berechnungen in Abhängigkeit von den zuerst verarbeiteten untergeordneten Elementen beinhalten .
quelle