Ich habe einen sehr großen Knotenbaum im Speicher und muss den Baum durchlaufen. Übergeben der zurückgegebenen Werte jedes untergeordneten Knotens an den übergeordneten Knoten. Dies muss getan werden, bis alle Knoten ihre Datenblase bis zum Wurzelknoten haben.
Traversal funktioniert so.
private Data Execute(Node pNode)
{
Data[] values = new Data[pNode.Children.Count];
for(int i=0; i < pNode.Children.Count; i++)
{
values[i] = Execute(pNode.Children[i]); // recursive
}
return pNode.Process(values);
}
public void Start(Node pRoot)
{
Data result = Execute(pRoot);
}
Dies funktioniert einwandfrei, aber ich bin besorgt, dass der Aufrufstapel die Größe des Knotenbaums begrenzt.
Wie kann der Code umgeschrieben werden, damit keine rekursiven Aufrufe Execute
erfolgen?
c#
optimization
trees
Reactgular
quelle
quelle
Antworten:
Hier ist eine allgemeine Tree Traversal-Implementierung, die keine Rekursion verwendet:
In deinem Fall kannst du es dann so nennen:
Verwenden Sie zuerst a
Queue
anstelle von aStack
für einen Atemzug und nicht zuerst die Tiefensuche. Verwenden Sie aPriorityQueue
für eine optimale erste Suche.quelle
Wenn Sie vorher eine Schätzung für die Tiefe Ihres Baums haben, reicht es in Ihrem Fall vielleicht aus, die Stapelgröße anzupassen? In C # seit Version 2.0 ist dies immer dann möglich, wenn Sie einen neuen Thread starten. Siehe hier:
http://www.atalasoft.com/cs/blogs/rickm/archive/2008/04/22/Erhöhen-der-Größe-Ihres-Stack-Net-Memory-Management-Teils-3.aspx
Auf diese Weise können Sie Ihren rekursiven Code beibehalten, ohne etwas Komplexeres implementieren zu müssen. Natürlich kann das Erstellen einer nicht rekursiven Lösung mit Ihrem eigenen Stack zeit- und speichereffizienter sein, aber ich bin mir ziemlich sicher, dass der Code nicht so einfach sein wird wie im Moment.
quelle
Sie können eine Datenstruktur nicht in Form eines Baums ohne Verwendung von Rekursion durchlaufen. Wenn Sie die von Ihrer Sprache bereitgestellten Stapelrahmen und Funktionsaufrufe nicht verwenden, müssen Sie im Grunde genommen Ihre eigenen Stapel- und Funktionsaufrufe programmieren Es ist unwahrscheinlich, dass Sie es auf effizientere Weise in der Sprache schaffen als die Compiler-Autoren auf dem Computer, auf dem Ihr Programm ausgeführt wird.
Das Vermeiden von Rekursionen aus Angst vor Ressourcenbeschränkungen ist daher in der Regel falsch. Sicher ist, dass eine vorzeitige Ressourcenoptimierung immer falsch ist. In diesem Fall ist es jedoch wahrscheinlich, dass Sie die Speichernutzung auch dann nicht verbessern können, wenn Sie den Engpass messen und bestätigen Compiler-Writer.
quelle