Hilf mir, Inorder Traversal ohne Rekursion zu verstehen
Ich bin in der Lage zu verstehen, preorder traversal ohne Verwendung von Rekursion, aber ich habe eine harte Zeit mit inorder traversal. Ich weiß einfach nicht scheinen, um es zu bekommen, vielleicht, weil ich noch nicht verstanden, die innere Arbeitsweise einer Rekursion.
Dies ist, was ich bisher ausprobiert habe:
def traverseInorder(node):
lifo = Lifo()
lifo.push(node)
while True:
if node is None:
break
if node.left is not None:
lifo.push(node.left)
node = node.left
continue
prev = node
while True:
if node is None:
break
print node.value
prev = node
node = lifo.pop()
node = prev
if node.right is not None:
lifo.push(node.right)
node = node.right
else:
break
Den inneren while-Schleifen fühlt sich einfach nicht richtig. Auch, einige der Elemente sind immer zweimal gedruckt; vielleicht kann ich dies lösen, indem man prüft, ob dieser Knoten hat schon gedruckt vor, aber das erfordert eine andere variable, die wiederum fühlt sich nicht richtig an. Wo mache ich falsch?
Ich habe nicht versucht, postorder-Traversierung, aber ich denke, es ist ähnlich und ich werde mit den gleichen konzeptionellen Blockade auch da.
Vielen Dank für Ihre Zeit!
P. S.: Definitionen von Lifo
und Node
:
class Node:
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
class Lifo:
def __init__(self):
self.lifo = ()
def push(self, data):
self.lifo = (data, self.lifo)
def pop(self):
if len(self.lifo) == 0:
return None
ret, self.lifo = self.lifo
return ret
InformationsquelleAutor der Frage Srikanth | 2010-01-22
Du musst angemeldet sein, um einen Kommentar abzugeben.
Beginnen Sie mit der rekursive Algorithmus (pseudocode) :
Dies ist ein klarer Fall von tail-Rekursion, so können Sie ganz einfach schalten Sie ihn in eine while-Schleife.
Du bist Links mit einem rekursiven Aufruf. Was der rekursive Aufruf funktioniert, drücken Sie in einem neuen Kontext auf den stack, führen Sie den code von Anfang an, dann rufen Sie die Kontext-und weiterhin das tut, was es tut. So erstellen Sie einen Stapel für Lagerung, und eine Schleife, die bestimmt, bei jeder iteration, ob wir in einer "first run" - situation (nicht-null-Knoten) oder eine "Rückkehr" - situation (null-Knoten, nicht-leeren stack) und führt den entsprechenden code:
Die schwierige Sache zu begreifen, ist die "Rückkehr" Teil: Sie haben zu bestimmen, in der Schleife, ob der code läuft bist du in der "Eingabe der Funktion-situation" oder in der "Rückkehr aus einem Aufruf" - situation, und Sie haben eine
if/else
Kette mit so viele Fälle wie Sie nicht-terminal-rekursionen in Ihrem code.In dieser konkreten situation, sind wir mit den Knoten, um Informationen über die situation. Ein anderer Weg wäre, zu speichern, die in dem Stapel selbst (genau wie ein computer wird für die Rekursion). Mit dieser Technik, der code ist nicht optimal, aber einfacher zu Folgen
InformationsquelleAutor der Antwort Victor Nicollet
Hier ist eine einfache in-order, nicht-rekursive c++ - code.
InformationsquelleAutor der Antwort Emadpres
InformationsquelleAutor der Antwort Ashish
PS: ich weiß nicht, Python, so dass es vielleicht ein paar syntax-Probleme.
InformationsquelleAutor der Antwort Henk Holterman
Hier ist ein Beispiel, in order-Traversierung mit stack in c# (.Netto):
(für post, um iterative Sie kann sich beziehen auf: Post-order-Traversierung eines binären Baum ohne Rekursion)
Hier ist ein Beispiel mit besucht Flagge:
den Definitionen von binarytreenode, listtostring utility:
InformationsquelleAutor der Antwort Dreamer
Staat kann daran erinnert werden, implizit,
InformationsquelleAutor der Antwort
@Victor, ich habe einige Vorschläge auf Ihre Umsetzung versucht, den Zustand in den Stapel. Ich sehe es nicht notwendig ist. Denn jedes element, das Sie nehmen von dem Stapel ist schon Weg durchquert. anstatt also speichern der Informationen in dem stack, alles, was wir brauchen, ist ein flag, das angibt, ob der nächste Knoten verarbeitet werden, ist von diesem stack oder nicht. Folgende ist meine Umsetzung, die gut funktioniert:
InformationsquelleAutor der Antwort Leonmax
Wenig Optimierung der Antwort von @Emadpres
InformationsquelleAutor der Antwort om471987
Kann dies vielleicht hilfreich sein (Java-Implementierung)
InformationsquelleAutor der Antwort Stuck in Java
Einfache iterative inorder-Traversierung ohne Rekursion
InformationsquelleAutor der Antwort yask
InformationsquelleAutor der Antwort Siddhartha
Hier ist eine iterative C++ - Lösung als alternative zu dem, was @Emadpres geschrieben:
InformationsquelleAutor der Antwort jpswain
Hier ist ein iterativer Python-Code für den Inorder Traversal ::
InformationsquelleAutor der Antwort harrypotter0
Ich denke, Teil des Problems ist die Verwendung des "zurück" - variable. Sie sollten nicht speichern die vorherigen Knoten sollten Sie in der Lage sein, um den Zustand zu verwalten, die auf dem stack (Lifo) selbst.
Vom Wikipedia, den Algorithmus, den Sie anstreben, ist:
In pseudo-code (disclaimer, ich weiß nicht, Python, so Entschuldigung für die Python/C++ - Stil-code unten!) dein Algorithmus wäre so etwas wie:
Für postorder-traversal-tauschen Sie einfach die Reihenfolge, die Sie drücken Sie den linken und rechten Teilbaum auf den stack.
InformationsquelleAutor der Antwort Paolo