Dokumentation zum AVL-Baum (C++) Christian Blaar Monique Argus Januar 2007 Institut für Informatik Martin-Luther-Universität Halle-Wittenberg 1 1 NODE.H 1 Node.h Node legt die Grundlage für jeden Baum, denn hier werden die einzelnen Elemente, Blätter oder Knoten als Abstrakter Datentyp zur Verfügung gestellt. Es wird ein Knoten mit einem Wert val erzeugt, der Verweise auf Elternknoten, sowie Kindknoten besitzt. Die Klasse enthält außerdem Methoden um die Werte der „Nachbarknoten“ auszulesen oder zu setzen. val 1.1 Deklaration template<class T> class Node { !!! T value; !!! int bal; !!! Node<T>* parent; !!! Node<T>* leftChild; !!! Node<T>* rightChild; ! public: !!! Node(T); !!! ∼Node(); !!! T& getValue(); !!! void setValue(T); !!! Node<T>* getParent(); !!! Node<T>* getLeft(); !!! Node<T>* getRight(); !!! Node<T>* setParent(Node<T>*); !!! Node<T>* setLeft(Node<T>*); !!! Node<T>* setRight(Node<T>*); !!! void deleteLeft(); !!! void deleteRight(); !!! void deleteParent(); !!! void setLeftNull(); !!! void setRightNull(); !!! void setParentNull(); !!! int getBal(); !!! void setBal(int); }; 2 1.2 Konstruktoren und Destruktor 1.2 1 NODE.H Konstruktoren und Destruktor Node(T val) Der Konstruktor legt den Wert des Knoten mit val fest, die Balance ist 0 und Elternknoten, linkes und rechtes Kind sind Nullzeiger. ∼Node Der Destruktor löscht einen Knoten. 1.3 Methoden void deleteLeft() Löscht das linke Objekt und setzt an dessen Stelle einen Nullzeiger. void deleteParent() Löscht den Elternknoten und setzt an dessen Stelle einen Nullzeiger. void deleteRight() Löscht das rechte Objekt und setzt an dessen Stelle einen Nullzeiger. int getBal() Liefert die Balance des Baumes zurück. Node<T>* getLeft() Gibt den Wert des linken Kindes als Referenz zurück. Node<T>* getParent() Gibt den Elternknoten eines Knotens als Referenz zurück. Node<T>* getRight() Gibt den Wert des rechten Kindes als Referenz zurück. T& getValue() Die Methode getValue liefert den Wert eines Knotens zurück void setBal(int balance) Setzt die Balance des Baumes auf balance. Node<T>* setLeft(Node<T>* myNode) Setzt das linke Kind und liefert eine Selbstreferenz zurück. void setLeftNull() Setzt Nullzeiger als linkes Kind. Node<T>* setParent(Node<T>* myNode) Setzt den Elternknoten und liefert eine Selbstreferenz zurück. void setParentNull() Setzt Nullzeiger als Elternknoten. 3 1.3 Methoden 1 NODE.H Node<T>* setRight(Node<T>* myNode) Setzt das rechte Kind und liefert eine Selbstreferenz zurück. void setRightNull() Setzt Nullzeiger als rechtes Kind. void setValue(T val) Setzt den Wert eines Knotens. 4 2 AVLTREE.H 2 AVLTree.h Die Klasse AVLTree liefert mit Hilfe des ADT Node und Templates den ADT AVL-Baum. Hiermit kann ein Baum aufgebaut und entsprechend Knoten eingefügt bzw. gelöscht werden, sowie ihr Vorhandensein überprüft und der Baum gelöscht werden. 2.1 Deklaration template<class T> class AVLTree{ !!! Node<T>* root; !!! void maxLeft(T, Node<T>*); !!! int rebalance(T, Node<T>*); !!! void rotateRight(int, Node<T>*); !!! void rotateLeft(int, Node<T>*); !!! void rotateDoubleLeft(int, Node<T>*); !!! void rotateDoubleRight(int, Node<T>*); !!! int rebalance_del(T, Node<T>*); !!! std::vector<T> internalRangeQuery(T, T, Node<T>*); !!! int getHeight(Node<T>*); ! public: !!! AVLTree(); !!! AVLTree(T); !!! ∼AVLTree(); !!! void clear(); !!! bool find(T); !!! int insert(T); !!! int del(T); !!! std::vector<T> rangeQuery(T, T); !!! int getHeight(); }; 2.2 Konstruktoren und Destruktor AVLTree() Dieser (Standard-)Konstruktor erzeugt einen leeren Baum. Die Wurzel ist ein Nullzeiger. AVLTree(T val) Der Konstruktor bekommt einen Wert vom Typ T übergeben und konstruiert eine Wurzel mit dem Wert val. ∼AVLTree() Der Destruktor löscht die Wurzel und somit den gesamten Baum. 5 2.3 Methoden 2.3 2 AVLTREE.H Methoden void clear() Die Methode clear löscht die Wurzel, wodurch der gesamte Baum gelöscht ist. int del(T val) Es wird ein Wert val übergeben, dessen zugehöriger Knoten aus dem Baum gelöscht werden soll. Dabei wird 0 zurückgegeben, wenn nicht gelöscht werden musste, da der Knoten nicht vorhanden war, andernfalls 1. Auch hier wird eine Neubalancierung des AVL-Baums vorgenommen, wenn nötig. int getHeight() Gibt die Höhe des Baumes zurück. Der leere Baum hat die Höhe -1, während der Baum, der nur aus der Wurzel besteht, die Höhe 0 hat. int insert(T val) Die Methode insert fügt einen Knoten mit Wert val entsprechend der Regeln eines Binärbaumes ein. Es wird 0 zurückgegeben, wenn das Element bereits im Baum enthalten war, sonst 1. Es wird außerdem geprüft, ob die AVL-Eigenschaft nach dem Einfügen noch erfüllt ist und gegebenenfalls eine Methode zum Rotieren aufgerufen. bool find(T val) Die Methode find bekommt einen Wert val übergeben und überprüft, ob val im betrachteten Baum enthalten ist. Die Methode liefert 0 zurück, wenn das Element nicht enthalten ist, andernfalls 1. std::vector<T> rangeQuery(T min, T max) Diese Methode gibt alle Werte min ≤ v ≤ max des Baumes zurück. 6 3 ANWENDUNGSBEISPIEL 3 Anwendungsbeispiel Es soll ein AVL-Baum erstellt werden in den, der Reihe nach, die Knoten mit den Werten 1, 2 und 3 eingefügt werden. Dann wird überprüft, ob alle 3 Knoten vorhanden sind. Zuletzt wird ein Knoten gelöscht und wieder geprüft ob alle 3 Knoten vorhanden sind. Wir nennen diese Datei hier Test.cpp #include ”AVLTree.h” #include <iostream> using std::cout; int main() { \* ein neues Objekt vom Typ AVLTree erzeugen *\ !!! AVLTree<int>* Baum = new AVLTree<int>; \* nun können die 3 Knoten eingefügt werden *\ !!! Baum->insert(1); !!! Baum->insert(2); !!! Baum->insert(3); \* Prüfen, ob alle Knoten vorhanden sind *\ !!! cout < < Baum->find(1) < < ” \n”; !!! cout < < Baum->find(2) < < ”\n”; !!! cout < < Baum->find(3) < < ”\n”; \* löschen des Knotens 1 *\ !!! Baum->del(1); \* erneutes Prüfen, ob alle Knoten vorhanden sind *\ !!! cout < < Baum->find(1) < < ”\n”; !!! cout < < Baum->find(2) < < ”\n”; !!! cout < < Baum->find(3) < < ”\n”; } Mit Hilfe des Aufrufs user> g++ -o Test Test.cpp wird die Datei nun Übersetzt und kann mit user> ./Test ausgeführt werden. Ausgabe ist dann folgende: user> ./Test 1 1 1 0 1 1 7