Inhaltsverzeichnis

Levelorder Traversierung, Iterative Tiefensuche

Bei den drei rekursiv implementierbaren Traversierungen wird der Baum zuerst in die Tiefe durchwandert bis hin zu seinen Blättern ("Tiefensuche"). Manchmal möchte man aber einen Baum auf jedem Level von links nach rechts (oder andersherum) durchlaufen, also Level für Level. Das nennt man "Level-Order-Traversierung":

Bei der Levelorder Traversierung werden auf jedem Niveau des Baums erst alle Knoten besucht, bevor auf das nächste Niveau gewechselt wird, in unserem Beispielbaum ergibt sich damit die Traversierungsreihenfolge: A→B→F→C→D→G→E. Der Algorithmus zur Levelorder Traversierung ist nicht rekursiv.

In diesem Wiki-Abschnitt wollen wird zunächst die Rekursiven Traversierungen iterativ umschreiben, um uns anschließend zu überlegen, wie man die Level-Order-Traversierung (oder Breitensuche) implementiert.

Iterative Traversierung

Die rekursiven Implementationen der Traversierungen versagen ihren Dienst, wenn die Bäume zu tief werden, da der Call-Stack für die Rekursion nicht beliebig wachsen kann. Bei Java ist seine Größe auf ca. 256kB beschränkt, wenn diese Größe überschritten wird, erhältst du einen Stack Overflow Error:

Die einfachste Lösung für dieses Problem ist es, den Stack, in dem man darüber Buch führt, welche Knoten des Baums als nächstes zu bearbeiten sind, selbst zu verwalten:

Von der Rekursion zur Iteration

Die folgende Tabelle stellt den rekursiven Pseudocode zur Ermittlung der Knotenzahl einer iterativen Variante gegenüber.

Rekursiv Iterativ
anzahl(b: Binaerbaum): 
  falls b == null: 
    return 0 
  sonst: 
    t1 = anzahl(b.links) 
    t2 = anzahl(b.rechts)
    return 1 + t1 + t2
anzahl(b: Binaerbaum):
  todo = new Stack
  todo.push(b)
  zaehler = 0
  solange todo nicht leer:
    tmp = todo.pop()
    zaehler++ 
    falls tmp.rechts != null:
      todo.push(tmp.rechts)
    falls tmp.links != null:
      todo.push(tmp.links)
  return zaehler

Während die rekursive Variante die Verwaltung der noch zu bearbeitenden Knoten dem Aufrufstack der Rekursion überlässt, implementiert die iterative Variante einen eigenen "todo"-Stack mit, dem die den in den nächsten Schritten zu verarbeitenden Knoten verwaltet werden.

Suche im Baum

(A1) Tiefensuche

Arbeite mit der folgenden Bluej-Vorlage: https://codeberg.org/qg-info-unterricht/binaerbaum-iterativ

Du kannst in der Klasse "Testbaeume" anpassen, welche Baumdefinitionen geladen werden sollen: Entweder 100 "große" Bäume oder 5 "kleine" Bäume.


(A2) Breitensuche

Material

FilenameFilesizeLast modified
baeume_traversierung_iterativ.odp106.8 KiB14.02.2022 15:21
baeume_traversierung_iterativ.pdf170.4 KiB14.02.2022 15:21
levelorder.gif44.1 KiB14.02.2022 20:37
stackoverflow.png13.9 KiB14.02.2022 15:24