Können Sie es anstelle einer Rekursion in Iteration ändern?
Sie können einen expliziten Stapel verwenden. Pseudocode:
%Vor%Aber das ist dem rekursiven Code nicht wirklich überlegen (abgesehen von der fehlenden Basisbedingung in Ihrem Code).
Was Sie suchen, ist ein Nachfolgeralgorithmus.
So kann es definiert werden:
Wie Sie sehen können, benötigen Sie dazu einen übergeordneten Knotenzeiger.
(1)
(1)
keinen rechten Teilbaum hat, gehen wir zu (3)
. Dies ist eine Rechtskurve, also ist (3)
next. (3)
über einen rechten Teilbaum verfügt, ist der Knoten ganz links in diesem Teilbaum der nächste: (4)
. (4)
keinen rechten Teilbaum hat, gehen wir zu (6)
. Dies ist eine Rechtskurve, daher ist (6)
. (6)
über einen rechten Teilbaum verfügt, ist der Knoten ganz links in diesem Teilbaum der nächste: (7)
. (7)
keinen rechten Teilbaum hat, gehen wir zu (6)
. Dies ist eine Linkskurve, also gehen wir weiter zu (3)
. Dies ist eine Linkskurve, also gehen wir weiter zu (8)
. Dies ist eine Rechtskurve, daher ist (8)
. (8)
über einen rechten Teilbaum verfügt, ist der Knoten ganz links in diesem Teilbaum der nächste: (10)
. (10)
über einen rechten Teilbaum verfügt, ist der Knoten ganz links in diesem Teilbaum der nächste: (13)
. (13)
keinen rechten Teilbaum hat, gehen wir zu (14)
. Dies ist eine Rechtskurve, daher ist (14)
. (14)
keinen rechten Teilbaum hat, gehen wir zu (10)
. Dies ist eine Linkskurve, also gehen wir weiter zu (8)
. Dies ist eine Linkskurve, also wollen wir weiter nach oben gehen, aber da (8)
kein Elternteil hat, haben wir das Ende erreicht. (14)
hat keinen Nachfolger. Hier ist eine einfache Implementierung des obigen Algorithmus:
%Vor%Dann können Sie einen Test-Kabelbaum wie folgt haben:
%Vor%Dies druckt:
%Vor%Sicher, Sie haben zwei allgemeine Algorithmen: erste Tiefensuche und weitere Suche .
Wenn die Reihenfolge der Traversierung für Sie nicht wichtig ist, wählen Sie zuerst die Breite, dann ist es einfacher, sie für die Iteration zu implementieren. Dein Algorithmus sollte ungefähr so aussehen.
%Vor%Wie bei jeder Rekursion können Sie eine zusätzliche Datenstruktur verwenden - also den Stack. Eine Skizze der Lösung :
%Vor%Ja, Sie können es anstelle einer Rekursion in Iteration ändern, aber dann wird es viel komplizierter, da Sie eine Möglichkeit haben müssen, sich zu erinnern, wo Sie vom aktuellen Knoten zurück gehen können. Im rekursiven Fall verarbeitet der Java-Aufruf-Stack das, aber in einer iterativen Lösung müssen Sie Ihren eigenen Stack erstellen oder vielleicht Zeiger in den Knoten speichern.
Ich hatte einen Baum (nicht binär) und löste ihn schließlich mit diesem sehr einfachen Algorithmus. Die anderen verwendeten Lösungen links und rechts waren in den Beispielen nicht relevant oder gar nicht implementiert.
Meine Struktur war: Knoten mit jedem Elternteil, der eine Liste von Kindern enthielt, und jedes Kind, das einen Zeiger zurück auf das Elternteil enthielt. Ziemlich häufig ...
Nach einigem Refactoring kam ich mit Kotlin zum folgenden Beispiel. Es sollte trivial sein, in die Sprache Ihrer Wahl zu konvertieren.
Zuerst muss der Knoten 2 einfache Funktionen bereitstellen. Dies hängt von der Implementierung Ihrer Knotenklasse ab:
leftMost - Dies ist der erste untergeordnete Knoten. Wenn dieser Knoten untergeordnete Elemente hat, ist es das erste untergeordnete Element usw. Wenn keine untergeordneten Objekte vorhanden sind, geben Sie das zurück.
%Vor%nextSibling - Das nächste gleichgeordnete Element dieses Knotens oder NULL
%Vor%Die Iteration beginnt mit dem leftMost der Wurzel.
Inspiziere dann das nächste Geschwister.
Das ist es.
Hier ist eine Kotlin-Iterator-Funktion.
%Vor%Hier ist die gleiche next () -Funktion, aber ohne die Kotlin-Kurzschrift für den Umgang mit NULL-Werten, für diejenigen, die nicht zur Syntax passen.
%Vor%Tags und Links algorithm java recursion traversal binary-tree