Wednesday 9 August 2017

Binärer Ausdruck

Binäre Bäume Was ist ein Baum Es ist eigentlich schwer zu definieren, was wir mit einem Baum meinen, aber die Idee kann in dem folgenden Bild eines Beispielbaums mit den Kursvoraussetzungen gesehen werden. Ein Kurs mit einer Linie zu einem zweiten Kurs darunter ist Voraussetzung für den zweiten Kurs. Die Reihenfolge von links nach rechts bedeutet nichts. Wir würden immer noch den gleichen Baum, wenn 330 waren auf der rechten Seite von 310, zum Beispiel. An dieser Stelle ist es hilfreich, einige Begriffe einzuführen. Der Stammknoten (oder einfach root) ist der Knoten am oberen Rand des Baumdiagramms. In unserem Fall ist es das eine mit 110. Beachten Sie, dass in der Informatik Bäume haben ihre Wurzel an der Spitze und verzweigen sich, wie Sie nach unten Dies ist einfach die übliche Art der Zeichnung von Bäumen. Der übergeordnete Knoten eines Knotens ist derjenige, der direkt von oben mit ihm verbunden ist. In unserem Beispiel ist 111 das übergeordnete Element von 350, 230 ist das übergeordnete Element von 310, 110 hat kein übergeordnetes Element usw. Ein Kind ist ein Knoten, der direkt unter dem Startknoten verbunden ist. Somit ist 350 ein Kind von 111, 310 ist ein Kind von 230 usw. Es ist einfach das Gegenteil der Elternbeziehung. Knoten mit demselben Elternteil werden als Geschwister bezeichnet. So sind 221, 230 und 350 Geschwister in unserem Beispiel. Ein Vorgänger eines gegebenen Knotens ist entweder das übergeordnete Element, das übergeordnete Element des übergeordneten Elements, das übergeordnete Element usw. In unserem Beispiel ist 110 ein Vorfahre aller anderen Knoten im Baum. Das Gegenstück des Ahnen ist Nachkomme. Beispielsweise ist 310 ein Abkömmling von 111, aber 310 ist kein Abkömmling von 221. Die Blätter eines Baums (manchmal auch als externe Knoten bezeichnet) sind jene Knoten ohne Kinder. In unserem Beispiel sind 221, 350, 330 und 310 Blätter. Beachten Sie, dass Blätter nicht auf der untersten Ebene im Baum sein müssen. Die anderen Knoten des Baums werden als Nicht-Blätter (oder manchmal interne Knoten) bezeichnet. Man beachte, dass jeder Knoten eines Baums als der Stamm eines Teilbaums angesehen werden kann, der aus diesem Knoten und allen seinen Nachkommen besteht. Zum Beispiel ist der Teilbaum, der bei 230 verwurzelt ist, folgendermaßen: Ein Zweig ist eine Folge von Knoten, so dass der erste der Elternteil des zweiten, der zweite der Elternteil des dritten usw. ist Sequenz 111, 230, 310 ist eine Verzweigung. Die Länge eines Zweigs ist die Anzahl der durchlaufenen Liniensegmente (die um eins kleiner ist als die Anzahl der Knoten). Der obige Zweig hat Länge 2. Die Höhe eines Baumes ist die maximale Länge eines Zweigs von der Wurzel zu einem Blatt. Der obige Baum hat die Höhe 3, da der längste mögliche Zweig von Wurzel zu Blatt entweder 110, 111, 230, 310 oder 110, 111, 230, 330 ist, die beide die Länge 3 haben. Eine formalere Definition eines Baumes kann sein Wie folgt: Ein (allgemeiner) Baum besteht aus einem Satz von Knoten, der entweder leer ist oder einen Wurzelknoten hat, an den null oder mehrere Teilbäume angehängt sind. Natürlich muss ein Teilbaum selbst ein Baum sein. Das ist also eine rekursive Definition. Beachten Sie auch, dass es keine Links-nach-Rechts-Reihenfolge der Teilbäume gibt. Was ist ein binärer Baum Ein binärer Baum ist ähnlich wie ein Baum, aber nicht ganz derselbe. Für einen binären Baum kann jeder Knoten null, ein oder zwei Kinder haben. Zusätzlich wird jeder Kindknoten eindeutig als das linke Kind oder das rechte Kind identifiziert. Somit gibt es eine definitive Links-Rechts-Ordnung der Kindknoten. Auch wenn ein Knoten nur ein Kind hat, muss dieses Kind entweder als das linke Kind oder das rechte Kind identifiziert werden. Als Beispiel ist hier der binäre Ausdrucksbaum für den Ausdruck 4 5 - 3. Beachten Sie, dass ein Kind, das links von seinem Elternteil gezeichnet wird, das linke Kind sein soll und dass ein Kind, das rechts von seinem übergeordneten Element gezeichnet wird, dazu bestimmt ist Das richtige Kind sein. Das Umkehren der linken bis rechten Ordnung eines Geschwisters ergibt einen anderen binären Baum. Beispielsweise ergibt das Umkehren der unter und bei 3 verwurzelten Teilbäume den folgenden unterschiedlichen Binärbaum. Es handelt sich um den binären Ausdrucksbaum für 3 - 4 5. Was ist ein binärer Suchbaum Ein binärer Suchbaum ist ein binärer Baum, in dem die Daten in den Knoten in einer bestimmten Weise geordnet sind. Um genau zu sein, beginnend bei jedem gegebenen Knoten, müssen die Daten in jedem Knoten seines linken Teilbaums alle kleiner sein als das Element in dem gegebenen Knoten, und die Daten in irgendwelchen Knoten seines rechten Teilbaus müssen größer oder gleich den Daten sein In dem gegebenen Knoten. Natürlich bedeutet dies alles, dass die Datenelemente durch eine Art von weniger als eine Beziehung geordnet werden können. Für Zahlen kann dies natürlich getan werden. Für Zeichenfolgen wird oft alphabetische Reihenfolge verwendet. Für Datensätze wird häufig ein Vergleich verwendet, der auf einem bestimmten Feld (dem Schlüsselfeld) basiert. Im Folgenden finden Sie einen binären Suchbaum, in dem jeder Knoten einen Personennamen enthält. Nur Vornamen werden verwendet, um das Beispiel einfach zu halten. Beachten Sie, dass die Namen alphabetisch geordnet sind, so dass DAVE vor DAWN kommt, DAVID kommt vor DAWN aber nach DAVE, etc. Wie erstellt man einen binären Suchbaum in erster Linie Eine Möglichkeit, dies zu tun ist, indem Sie mit einem leeren binären Suchbaum beginnen Und das Hinzufügen der Datenelemente einzeln. Das erste Element wird zum Root. Das nächste Element wird, abhängig von der Reihenfolge, entweder in einen linken oder rechten untergeordneten Knoten platziert. Das dritte Element wird mit der Wurzel verglichen, wir gehen nach links oder nach rechts, je nach dem Ergebnis des Vergleichs usw., bis wir den Punkt dafür finden. In jedem Fall folgen wir einem Pfad von der Wurzel zu dem Punkt, an dem wir das neue Element einfügen, wobei wir das neue Element mit jedem Element in den Knoten verbinden, die entlang des Weges angetroffen werden, wobei an jedem Knoten nach links oder rechts gegangen wird, um die oben beschriebene Ordnung beizubehalten . Traversals of Binary Trees Es gibt mehrere bekannte Möglichkeiten, einen Binärbaum zu durchqueren, zu durchwandern. Wir werden drei davon betrachten. Das erste ist ein Inorder-Traversal. Dieser besteht aus drei Gesamtschritten: Durchlaufen Sie den linken Teilbaum (rekursiv), besuchen Sie den Wurzelknoten und überqueren Sie den rechten Teilbaum (rekursiv). Wenn wir einen Knoten besuchen, tun wir in der Regel einige Verarbeitung auf sie, wie das Drucken der Inhalt des Knotens. Zum Beispiel liefert ein Inorder-Traversal des obigen binären Suchbaums die Namen in dieser Reihenfolge: Beachten Sie, dass wir die Daten in aufsteigender Reihenfolge erhalten haben. Dies geschieht immer, wenn ein Inorder-Traversal eines binären Suchbaums ausgeführt wird. In der Tat, eine Art kann auf diese Weise getan werden. Einer fügt zuerst die Daten in einen binären Suchbaum ein und führt dann einen Inorderdurchlauf durch, um die Daten in aufsteigender Reihenfolge zu erhalten. Manche Leute nennen dies eine Baumart. Nun, wie genau haben wir die oben genannten Liste der Daten Im Wesentlichen haben wir dies, indem Sie die rekursive Definition für eine Inorder Traversal. Zuerst durchlaufen wir den linken Teilbaum der Wurzel, DAWN. Dieser linke Teilbaum ist derjenige, der bei DAVE verwurzelt ist. Wie können wir es durchlaufen, indem wir das gleiche dreistufige Verfahren verwenden. Wir durchqueren zuerst den linken Teilbaum, der an BETH verwurzelt ist. Natürlich müssen wir dann durch die drei Schritte auf dem Teilbaum gehen, der bei BETH verwurzelt ist. Wir beginnen, indem wir seinen linken Teilbaum durchqueren, aber er ist leer, also besuchen wir die Wurzel, BETH. Das ist das erste Datenelement, das gedruckt wird. Dann durchqueren wir den rechten Teilbaum, der an CINDI verwurzelt ist. Wir verwenden den dreistufigen Prozess darauf, aber da seine Teilbäume leer sind, drucken wir einfach den Stamm, CINDI, der die zweite Position ist gedruckt. Wir stützen uns dann auf, wo wir mit dem Teilbaum verbleiben, der bei DAVE verwurzelt ist. Wir haben nun seinen linken Teilbaum durchlaufen, also gehen wir weiter, um die Wurzel, DAVE, zu drucken und dann den rechten Teilbaum zu durchqueren. Da der rechte Teilbaum selbst leere Teilbäume hat, werden wir nur seine Wurzel, DAVID, drucken. Für den Rest dieses binären Suchbaums gehen wir in ähnlicher Weise vor. Die beiden anderen Traversals, die wir studieren werden, sind die Vororder-Traversal und die Postorder Traversal. Sie sind dem Inorder-Traversal sehr ähnlich, da sie aus denselben drei Stufen bestehen, aber leicht umgestellt werden. Der Vororderdurchlauf setzt den Schritt des Besuchens der Wurzel zuerst. Das Postorder-Traversal setzt den Schritt des Besuchs der Wurzel zuletzt. Alles andere bleibt gleich. Hier ist ein Überblick über die Schritte für alle drei unserer Traversals. Vorbestellen Traversal Besuchen Sie die root Traverse der linken Teilbaum Traverse der rechten Teilbaum Inorder traversal Traverse der linken Teilbaum Besuchen Sie die Wurzel Traverse der rechten Teilbaum Postorder-Traversal Traverse der linken Teilbaum Traversieren Sie den rechten Teilbaum Besuchen Sie die Wurzel Als Beispiel, können wir eine Postorder-Traversal der Binäre Ausdrucksbaum für 4 5 - 3, die wir früher angesehen haben. Der Baum wird der Einfachheit halber wieder gezeigt: Zuerst durchlaufen wir den linken Teilbaum des gesamten Binärbaums. Dies ist der Teilbaum, der verwurzelt ist. Dazu verwenden wir unsere drei Schritte. Wir durchqueren seinen linken Teilbaum, der zum Drucken führt 4. Dann durchqueren wir den rechten Teilbaum, der zum Drucken führt 5. Danach besuchen wir die Wurzel, Drucken. Als nächstes unterstützen wir bis zu dem, wo wir mit dem ganzen binären Baum aufgehört haben. Wir haben nun den linken Teilbaum durchquert, so dass wir den rechten Teilbaum durchqueren, drucken 3. Dann besuchen wir die Wurzel, Drucken -. Insgesamt sind wir am Ende drucken 4 5 3 -. Die Postfix-Form des Ausdrucks. Ein Postfix-Ausdruck wird entschlüsselt, indem man ihn von links nach rechts betrachtet und die Tatsache verwendet, daß jeder Operator (wie z. B.) auf die beiden vorhergehenden Werte zutrifft. Beachten Sie, dass der Traversal immer so funktioniert: Ein Postorder-Traversal eines binären Ausdrucksbaums ergibt die Postfix-Form des Ausdrucks. Sie können mit Postfix-Ausdrücken, dass einige Rechner verwenden sie vertraut sein. In der gewöhnlichen Mathematik werden wir verwendet, um Infix-Ausdrücke, wobei Operatoren wie und kommen zwischen den beiden Werten, auf die sie angewendet werden. Für die Praxis versuchen Sie eine Vororder-Durchquerung der gleichen binären Ausdrucksbaum für 4 5 - 3. Das Ergebnis sollte sein - 4 5 3. Dies ist die Präfixform des Ausdrucks, dh die Form, in der jeder binäre Operator den beiden Größen vorangeht Anzuwenden. Ein Vororder-Traversal eines binären Ausdrucksbaums gibt immer die Präfixform des Ausdrucks. Die natürliche Vermutung wäre dann, daß die Inorder-Transversale eines binären Expressionsbaumes die Infixform des Ausdrucks hervorbringen würde, aber das ist nicht ganz richtig. Mit dem obigen Ausdruck ist es wahr. Versuchen Sie jedoch den Infix-Ausdruck (12 - 3) 2. Hier werden Klammern verwendet, um anzuzeigen, dass die Subtraktion vor der Multiplikation erfolgen soll. Der binäre Ausdrucksbaum sieht folgendermaßen aus: Wie Sie überprüfen können, erzeugt ein Inorder-Traversal dieses binären Ausdrucksbaums 12 - 3 2. Dies ist die Infixform eines etwas anderen Ausdrucks, bei dem die Multiplikation vor der Subtraktion erfolgt. Das Problem ist, dass wir nicht die Klammern zurück. Es ist möglich, den Code für ein Inorder-Traversal zu ändern, so dass es immer parenthesizes Dinge, aber eine einfache Inorder Traversal gibt keine Klammern. Verwendung eines binären Suchbaums Ein binärer Suchbaum kann eine sehr nützliche Datenstruktur sein. Wir haben bereits gesehen, dass es verwendet werden kann, um eine Sortierroutine zu erstellen. Eine solche Art Routine ist normalerweise ziemlich schnell. Tatsächlich ist es Theta (n lg (n)) im Durchschnitt. Es hat jedoch einen schlechten schlimmsten Fall, nämlich wenn die Daten bereits in aufsteigender oder absteigender Reihenfolge sind. (Versuchen Sie es mit einer Liste von Datenelementen in der Reihenfolge und legen Sie sie eins nach dem anderen in einen binären Suchbaum. Was sieht dieser Baum aussehen Warum würde dies machen es langsam, um die Daten später zugreifen, wenn wir die Inorder Traversal) Ein weiteres Verwendet die Verwendung eines binären Suchbaums Datenpositionen zum schnellen Nachschlagen später. Im durchschnittlichen Fall ist es ziemlich schnell, ein neues Element in einen binären Baum einzufügen, denn im Durchschnitt sind die Daten relativ zufällig und der binäre Baum ist relativ buschig. (In einem solchen Baum ist bekannt, daß die Höhe des binären Baumes Theta (lg (n)) ist, so daß das Einfügen ein Theta (lg (n)) - Vorgang ist Binärbaum folgt demselben Muster, wie es verwendet wurde, wenn es eingefügt wurde. Somit ist die Suche Theta (lg (n)) im Durchschnitt. Um zum Beispiel GINA im Binärbaum oben zu sehen, vergleicht man GINA mit DAWN, dem Root. Da GINA größer ist, bewegen Sie sich zu dem richtigen Kind, MIKE. Jetzt vergleichen GINA zu MIKE. Da GINA kleiner ist, bewegen Sie sich zum linken Kind GINA. Vergleichen Sie nun GINA mit dem Element im Knoten, auch GINA, und wir sehen, dass wir ein Spiel haben. Alle Lookups sind so. Man startet an der Wurzel und folgt einem Pfad von der Wurzel zum passenden Element (oder zu einem Blatt, wenn keine Übereinstimmung gefunden wird). Eine zeigerbasierte Implementierung eines binären Suchbaums Es ist typisch, einen binären Suchbaum zu erstellen, indem Objekte als Knoten und Zeiger für die Verbindung der Knoten verwendet werden. Dies ist der gleiche Ansatz, den wir bei der Implementierung verketteter Listen verwendet haben. Die folgenden Dateien zeigen die Details an: Die itemtype. h-Datei stellt einfach ItemType ein. Den Typ für die Daten, die wir in unserem Binärsuchbaum speichern wollen. Dann wird bstnode. h verwendet, um die Klasse für die Knotenobjekte wie unten gezeigt einzurichten: Jeder Knoten hat ein Info-Feld, um ein Datenelement und zwei Pointer-Felder links und rechts für Zeiger auf das linke bzw. das rechte Kind zu halten. Es gibt einen Konstruktor für die Klasse mit Standardwerten von NULL für die beiden Zeigerparameter. Beachten Sie die Verwendung der Initialisierungsliste, um Element in das Info-Feld, LeftPtr in das linke Feld usw. zu kopieren. Es gibt auch eine GetInfo-Funktion, um die Daten aus einem Knotenobjekt zu extrahieren. Schließlich wird BSTNodePTr als Typname für einen Zeiger auf eines dieser Knotenobjekte eingerichtet. Die bstnode. cpp-Datei ist einfach zu folgen, so können Sie auf die bstree. h-Datei zu bewegen. Es setzt die Klasse BSTCLass wie folgt ein: Es gibt zwei Datenfelder, Count und Root. Beide privat. Count wird verwendet, um zu verfolgen, wie viele Elemente in dem binären Suchbaum platziert wurden. Root ist der Zeiger auf den Wurzelknoten des binären Suchbaums. Wie für die Klassenfunktionen gibt es private Hilfefunktionen und die öffentlich verfügbaren. Der Code für diese ist in der bstree. cpp-Datei. Die Operationen, die öffentlich zugänglich sind, sind: eine, um ein leeres binäres Suchbaumobjekt, einen Destruktor, eine Funktion zur Rückgabe der Anzahl von Elementen in dem binären Suchbaum zu konstruieren, eine Funktion, um zu ermitteln, ob der binäre Suchbaum leer ist, eine Funktion zu Fügen Sie ein neues Element ein, so dass wir nach Abschluss noch einen binären Suchbaum haben und eine Funktion, um ein Element im binären Suchbaum zu finden. Die privaten Hilfsfunktionen umfassen einen, um einen neuen Knoten (der ein gegebenes Datenelement und linke und rechte Zeiger enthält) herzustellen, eine Funktion, um den von einem Knoten verwendeten Raum freizugeben, eine Funktion, um den von den Knoten der Binärn verwendeten Raum zu löschen (Leaving es leer), eine Funktion, um den Raum freizugeben, der von einem Teilbaum verwendet wird, und eine Funktion, um zu versuchen, ein gegebenes Element in einem Teilbaum zu finden. Diese Funktion unterstützt die Funktion public Find bei der Ausführung ihrer Aufgabe. Betrachten wir nun den Code für die Klassenfunktionen. Der Konstruktor füllt ein NULL als Root und Null für den Count. Dieses Objekt repräsentiert einen leeren binären Suchbaum. Der Destruktor verwendet die ClearTree-Hilfefunktion, um alle Knoten im Baum auszulöschen. Als Destruktor wird das BSTClass-Objekt mit seinen Root - und Count-Feldern automatisch ausgelöscht. Beachten Sie, dass explizit alle außerhalb des BSTClass-Objekts verwendeten Speicherbereiche zurückgewonnen werden müssen, da diese nicht automatisch behandelt werden. Die ClearTree-Funktion funktioniert durch Aufruf der ClearSubtree-Funktion auf die Teilstruktur, die auf dem Gesamtstamm verwurzelt ist. Dadurch werden alle Knoten im binären Suchbaum gelöscht. Dann wird das Objekt gesetzt, um einen leeren binären Suchbaum richtig anzuzeigen. Der Code für die ClearSubtree-Funktion ist interessant und wird daher nachfolgend detailliert dargestellt. Man beachte, dass ihm ein Zeiger auf einen Knoten des binären Suchbaums übergeben wird, und dann folgt er einem Postorder-Traversalmuster, um alle Knoten des Teilbaums zu besuchen, der an dem gegebenen Knoten verwurzelt ist. Natürlich haben wir zwei rekursive Aufrufe zu ClearSubtree. Das Stopp-Case für die Rekursion ist, wenn wir einen NULL-Zeiger für Current haben. In solch einem Fall gibt es nichts, was getan werden muss, um den dort verwurzelten Teilbaum klar zu machen, da der Teilbaum leer ist. Warum haben wir ein Postorder-Traversal benutzt und nicht eine der anderen Transversalen Postorder wird verwendet, weil wir nur eine Wurzel loswerden können Knoten, nachdem wir alle Knoten in seinen Unterbäumen beseitigt haben. Wenn wir einen Wurzelknoten loswerden, bevor wir einen seiner Nachkommen loswerden, würden wir wahrscheinlich jeden Weg verlieren, diesen Nachkomme über unsere Hinweise zu erreichen. Die GetNode-Funktion verwendet den Konstruktor für die BSTNodeClass, um einen neuen Knoten zu erstellen. Dann wird geprüft, ob die dynamische Speicherzuordnung für diesen Knoten funktioniert. Dies ist genau das Verfahren, das wir verfolgten, als wir verknüpfte Listen implementierten. Die nächsten Klassen-Funktionen sind sehr einfach, also können Sie auf die Insert-Funktion springen. Sein Code ist unten eingefügt: Diese Funktion verwendet ein Paar von Zeigern, aktuelle Punkte auf dem Knoten, der gerade untersucht wird, und Parent, die auf den übergeordneten Knoten zeigt. Diese werden über eine Schleife vorgerückt, die den entsprechenden Vergleich des zu fügenden Elements mit dem Element am aktuellen Knoten durchführt, wobei es sich nach links oder rechts bewegt. Die Schleife wird gestoppt, wenn Current NULL ist und Parent auf den Knoten verweist, unter dem das neue Objekt platziert werden soll. Ein neuer Knoten, der das Element enthält, wird dann hergestellt und unter diesem Elternteil verbunden, entweder als das linke Kind oder das rechte Kind. Natürlich gibt es einen speziellen Fall, wenn Parent auch NULL ist. Dies bedeutet, dass Sie in einen leeren Baum einfügen und nur das Root-Feld des binären Suchbaumobjekts auf den neu hergestellten Knoten verweisen müssen. Die Suchfunktion verwendet einfach SubtreeFind. Beginnend an der Wurzel des gesamten binären Suchbaums. SubtreeFind wird als rekursive Funktion geschrieben und wird nachfolgend zur weiteren Untersuchung gezeigt: Die ersten beiden Fälle in dieser Funktion sind die Stopp-Fälle für die Rekursion. Wenn der aktuelle Zeiger NULL ist. Dann suchen wir einen leeren Baum und das Ergebnis ist, dass das Element nicht gefunden werden kann. Dies wird angezeigt, indem ein Wert von NULL zurückgegeben wird. Wenn wir eine Übereinstimmung haben, geben wir einen Zeiger auf den aktuellen Knoten zurück. Wenn der Wert, den wir suchen, kleiner als der im aktuellen Knoten ist, dann suchen wir (rekursiv) diese Knoten links Teilbaum. In ähnlicher Weise, wenn der Wert, den wir suchen, größer als die im aktuellen Knoten ist, suchen wir dann diesen Knoten rechten Unterbaum. Schließlich enthält die bsttest. cpp-Datei ein Testprogramm für eines unserer binären Suchbaumobjekte. Es fügt einfach einige Elemente in den Baum ein, versucht, einige Werte im Baum zu finden usw. Eine Tabelle, die auf einem binären Suchbaum basiert In der gleichen Weise, wie wir eine tabellbasierte Tabelle erstellt haben. Können wir eine Tabelle erstellen, die auf einem binären Suchbaum basiert. Beide Datenstrukturen erlauben es uns, Daten einzugeben und später abzurufen. Die neue Klasse (BSTTableClass) wird wiederum durch Vererbung aus der abstrakten Basisklasse RamTableBaseClass abgeleitet. Die Hauptänderung ist natürlich, dass ein BSTTableClass-Objekt ein BSTClass-Objekt (ein binärer Suchbaum) und kein ListClass-Objekt (eine verknüpfte Liste) enthält. Schauen Sie durch die folgenden Dateien, um die Details zu sehen. Die folgende Abbildung zeigt die Zusammenhänge zwischen den Klassen, die beim Entwurf der obigen Software verwendet werden. Die Zeichnung enthält auch jene Klassen, die in der tabellarischen Tabelle verwendet werden, die früher entworfen wurde, da sowohl die Listenbasierte Tabelle als auch der Binärsuchbaumtyp der Tabelle von derselben abstrakten Basisklasse abgeleitet sind. Ähnliche Artikel: PowerPoint Präsentation: Sahnis Vorlesung 19 diskutiert arithmetische Ausdrücke, Postfix und Präfix Notation und Ausdruck Bäume: Folien 19ndash38 Betrachten Sie den Knoten für eine doppelt verkettete Liste: Nun ändern Sie die Links, so dass sie nicht horizontal, sondern vertikal sind. Wir können nun einen binären Ausdruck (wie wir in der normalen Arithmetik begegnen) als einen sogenannten binären Ausdrucksbaum 151 darstellen, wobei die Verknüpfungen Elternteilbeziehungen darstellen. Zum Beispiel könnte (AB) ((CD) (EF)) so dargestellt werden, dass EF bedeutet, dass E auf die F-Leistung erhöht wird: Wie im Baumstrukturverzeichnis (das Sie aus dem Dateisystem Ihres Computers kennen), ist der Einstiegspunkt Wird in diesem Fall das Quototkot 151 genannt, die Multiplikation. Der Link nach links verbindet sich mit dem Ausdruck, der der linke Operand ist, während der Link nach rechts mit dem Ausdruck verbindet, der der rechte Operand ist. Die Knoten, die keine Kinder haben (dh die Variablen A bis F), werden als quadratische Knotenknoten bezeichnet. Sie haben null Verweise für links und rechts. Wir können nun einen Weg definieren, um alle Knoten zu durchlaufen, genauso wie für eine verkettete Liste 151, die so genannte Tree Traversal. Nun haben wir jedoch das Problem, dass wir beide Wege gehen müssen. Wie immer ist Rekursion Ihr Freund. Der Punkt, an dem wir das Element für einen gegebenen Knoten verarbeiten, gibt uns verschiedene Traversals: Wenn wir es tun, sobald wir mit der Verarbeitung des Knotens beginnen, haben wir ein sogenanntes Prepre-Orderquot-Traversal. Wenn wir es tun, nachdem wir beide Kinder bearbeitet haben, haben wir ein sogenanntes Quotpost-Orderquot-Traversal. Schließlich, wenn wir es zwischen der Verarbeitung des linken Kindes und dem rechten Kind tun, haben wir eine quotin-orderquot Durchquerung. Wenn unsere einzige Aktion bei der Verarbeitung eines Knotens ist, das Element zu schreiben, bestimmt die Reihenfolge des Durchlaufs die Art des Ausdrucks, den wir ausschreiben: ein Pre-Order-Traversal schreibt, was ein Präfix-Ausdruck eine Post-Order Traversal genannt wird schreiben Einen Postfix-Ausdruck aus. Die Transformation in der Reihenfolge schreibt jedoch einen Ausdruck, der nicht notwendigerweise mit dem Ausdruck übereinstimmt (da es keine Klammern gibt). (: Sie sollten in der Lage sein, herauszufinden, die Methode public void inOrder (TreeNode Knoten) selbst.) Führen Sie eine Vor-Order Traversal auf dem Baum und schreiben Sie das Ergebnis. Führen Sie eine Traversierung nach dem Auftrag auf dem Baum durch und schreiben Sie das Ergebnis aus. Machen Sie eine in-Reihenfolge Traversal auf dem Baum und schreiben Sie das Ergebnis. Der Baum kann sehr einfach aus dem Präfix-Ausdruck generiert werden: Um an Baumknoten zu generieren (Rückgabe der Referenz auf den Knoten) Generieren Sie den Knoten mit Nullreferenzen nach links und rechts. Wenn das quottokenquot ein Operand ist, geben Sie einfach den Verweis auf den (Blatt-) Knoten zurück Ansonsten Rekursiv einen Baumknoten erzeugen und als linker Unterbaum verknüpfen Rekursiv einen Baumknoten erzeugen und als rechten Unterbaum verknüpfen Geben Sie den Verweis auf den resultierenden (internen ) Knoten Wenn Sie eine binäre Ausdrucksstruktur haben, können Sie die Arithmetik sehr einfach ausführen: So werten Sie einen Knoten in einem Ausdrucksbaum aus Wenn der Knoten ein Blattknoten (ein Operand) ist, geben Sie einfach den Wert zurück Ansonsten Rekursiv den linken Teilbaum auswerten und erhalten Dessen Wert Rekursiv den rechten Teilbaum auswerten und seinen Wert erhalten Führen Sie den durch den Operator angegebenen Vorgang aus und geben Sie THAT-Wert zurück. Wenn Sie einen binären Ausdrucksbaum angeben, können Sie den in Klammern stehenden Infix-Ausdruck schreiben, indem Elemente aller drei Traversals kombiniert werden: Zum Schreiben des Ausdrucks, der startet An diesem Knoten Wenn der Knoten ein Operator ist, schreiben Sie die geöffnete Klammer 151 Vorbestellungsposition Wenn ein linker untergeordneter Knoten vorhanden ist, schreiben Sie rekursiv den Infix-Ausdruck für diesen Knoten Schreiben des aktuellen Knotensymbols 151 In-order Position Wenn es einen gibt Rechter Kindknoten rekursiv den Infix-Ausdruck für diesen Knoten schreiben Wenn der Knoten ein Operator ist, schreiben Sie die enge Klammer 151 Post-Order-Position Java Code Beispiel 151 Prefix Expression Calculator ExpressionTree. java Die Expression Tree-Klasse enthält die TreeNodes-Objekte (link to Das gleiche wie eine Textdatei) 151 195 Zeilen PrefixCalc. java Der Präfixrechner, der ein ExpressionTree-Objekt ausführt (Verknüpfung mit demselben Textdatei) 151 44 Zeilen ExpressionTree. rtf Klasse Handout mit dem obigen Code als zwei Seiten von zwei - Spaltentext. PDF PrefixCalc. jar Ausführbare jar-Datei java - jar PrefixCalc. jar, die auch die oben genannten Java-Quelldateien enthält. PrefixCalc. exe Das gleiche in einem JSmooth. exe-Wrapper


No comments:

Post a Comment