Level-order-Traversierung eines binären Suchbaums

Level-order-Traversierung eines binären Suchbaums, das heißt, Ebene für Ebene zu traversieren, die Knoten jeder Ebene in einer Warteschlange zu speichern und dann Dequeue- (Knoten entnehmen) und Enqueue-Operationen (Knoten der nächsten Ebene speichern) durchzuführen, um den Zweck der Traversierung zu erreichen.

Durch die Einführung einer Warteschlange zur Unterstützung der Level-order-Traversierung:

  • Wenn der Wurzelknoten leer ist, gibt es nichts zu traversieren;

  • Wenn der Wurzelknoten nicht leer ist:

    • Zuerst den Wurzelknoten in die Warteschlange einreihen;

    • Solange die Warteschlange nicht leer ist:

      • Den vordersten Knoten der Warteschlange entnehmen und ihn traversieren;
      • Wenn der vorderste Knoten der Warteschlange ein linkes Kind hat, das linke Kind in die Warteschlange einreihen;
      • Wenn der vorderste Knoten der Warteschlange ein rechtes Kind hat, das rechte Kind in die Warteschlange einreihen;

Die folgenden Schritte werden nacheinander veranschaulicht:

(1)Zuerst den Wurzelknoten entnehmen und in die Warteschlange einfügen

(2)Entnehme 29, reihe die linken und rechten Kindknoten in die Warteschlange ein

(3)Der vordere Knoten 17 wird aus der Warteschlange entfernt, und seine Kindknoten 14 und 23 werden in die Warteschlange eingefügt.

(4)31 wird aus der Warteschlange entfernt, und seine Kindknoten 30 und 43 werden in die Warteschlange eingefügt.

(5)Zum Schluss alle aus der Warteschlange entfernen

Kerncode-Beispiel:
...
// Levelorder-Durchquerung des binären Suchbaums
public void levelOrder(){

    // Wir verwenden LinkedList als unsere Warteschlange
    LinkedList<Node> q = new LinkedList<Node>();
    q.add(root);
    while( !q.isEmpty() ){

        Node node = q.remove();

        System.out.println(node.key);

        if( node.left != null )
            q.add( node.left );
        if( node.right != null )
            q.add( node.right );
    }
}
...

Java-Beispielcode

Quellcode-Paket-Download:Herunterladen

src/example/binary/LevelTraverse.java Datei-Code:

package example.binary;

import java.util.LinkedList;

/**
* Level-Order-Durchlauf
 */

public class LevelTraverse<Key extends Comparable<Key>, Value>{

    // Die Knoten im Baum sind eine private Klasse; die Außenwelt muss die spezifische Implementierung der Knoten des binären Suchbaums nicht kennen.
    private class Node {
        private Key key;
        private Value value;
        private Node left, right;

        public Node(Key key, Value value) {
            this.key = key;
            this.value = value;
            left = right = null;
        }
    }

    private Node root;  // Wurzelknoten
    private int count;  // Anzahl der Knoten im Baum

    // Konstruktor, erstellt standardmäßig einen leeren binären Suchbaum
    public LevelTraverse() {
        root = null;
        count = 0;
    }

    // Gibt die Anzahl der Knoten im binären Suchbaum zurück
    public int size() {
        return count;
    }

    // Gibt zurück, ob der binäre Suchbaum leer ist
    public boolean isEmpty() {
        return count == 0;
    }

    // Fügt ein neues Datenpaar (Schlüssel, Wert) in den binären Suchbaum ein
    public void insert(Key key, Value value){
        root = insert(root, key, value);
    }

    // Prüft, ob der Schlüssel im binären Suchbaum existiert
    public boolean contain(Key key){
        return contain(root, key);
    }

    // Durchsucht den binären Suchbaum nach dem Wert, der dem Schlüssel entspricht. Wenn der Wert nicht vorhanden ist, wird null zurückgegeben
    public Value search(Key key){
        return search( root , key );
    }

    // Preorder-Durchlauf des binären Suchbaums
    public void preOrder(){
        preOrder(root);
    }

    // Inorder-Durchlauf des binären Suchbaums
    public void inOrder(){
        inOrder(root);
    }

    // Postorder-Durchlauf des binären Suchbaums
    public void postOrder(){
        postOrder(root);
    }

    // Levelorder-Durchquerung des binären Suchbaums
    public void levelOrder(){

        // Wir verwenden LinkedList als unsere Warteschlange
        LinkedList<Node> q = new LinkedList<Node>();
        q.add(root);
        while( !q.isEmpty() ){

            Node node = q.remove();

            System.out.println(node.key);

            if( node.left != null )
                q.add( node.left );
            if( node.right != null )
                q.add( node.right );
        }
    }

    //********************
    //* Hilfsfunktionen für den binären Suchbaum
    //********************

    // Knoten (key, value) in den bei node verwurzelten binären Suchbaum einfügen, unter Verwendung eines rekursiven Algorithmus
    // Gibt die Wurzel des binären Suchbaums nach dem Einfügen des neuen Knotens zurück
    private Node insert(Node node, Key key, Value value){

        if( node == null ){
            count ++;
            return new Node(key, value);
        }

        if( key.compareTo(node.key) == 0 )
            node.value = value;
        else if( key.compareTo(node.key) < 0 )
            node.left = insert( node.left , key, value);
        else    // key > node->key
            node.right = insert( node.right, key, value);

        return node;
    }

    // Prüft, ob der bei node verwurzelte binäre Suchbaum einen Knoten mit Schlüsselwert key enthält, unter Verwendung eines rekursiven Algorithmus
    private boolean contain(Node node, Key key){

        if( node == null )
            return false;

        if( key.compareTo(node.key) == 0 )
            return true;
        else if( key.compareTo(node.key) < 0 )
            return contain( node.left , key );
        else // key > node->key
            return contain( node.right , key );
    }

    // Finde den Wert, der key im binären Suchbaum mit Wurzel node entspricht, rekursiver Algorithmus
    // Gib NULL zurück, wenn der Wert nicht existiert
    private Value search(Node node, Key key){

        if( node == null )
            return null;

        if( key.compareTo(node.key) == 0 )
            return node.value;
        else if( key.compareTo(node.key) < 0 )
            return search( node.left , key );
        else // key > node->key
            return search( node.right, key );
    }

    // Führe eine Preorder-Traversierung auf dem binären Suchbaum mit Wurzel node durch, rekursiver Algorithmus
    private void preOrder(Node node){

        if( node != null ){
            System.out.println(node.key);
            preOrder(node.left);
            preOrder(node.right);
        }
    }

    // Führe eine Inorder-Traversierung auf dem binären Suchbaum mit Wurzel node durch, rekursiver Algorithmus
    private void inOrder(Node node){

        if( node != null ){
            inOrder(node.left);
            System.out.println(node.key);
            inOrder(node.right);
        }
    }

    // Führe eine Postorder-Traversierung auf dem binären Suchbaum mit Wurzel node durch, rekursiver Algorithmus
    private void postOrder(Node node){

        if( node != null ){
            postOrder(node.left);
            postOrder(node.right);
            System.out.println(node.key);
        }
    }
   
}
Weitere Erweiterungen