1#include <iostream>
2#include <algorithm>
3using namespace std;
4
5class Node { // Ein Knoten enthält seinen Wert und Zeiger auf seine beiden Kinder
6private: // Private Attribute: nur die Methoden greifen darauf zu
7 int value;
8 Node* left;
9 Node* right;
10public:
11 Node(int v) : value(v), left(nullptr), right(nullptr) {}
12 int getValue() const { return value; }
13 Node* getLeft() const { return left; }
14 Node* getRight() const { return right; }
15 void setValue(int v) { value = v; }
16 void setLeft(Node* n) { left = n; }
17 void setRight(Node* n) { right = n; }
18};
19
20int height(Node* n) { // Höhe: ein Blatt ist 1 und eine freie Stelle (nullptr) ist 0
21 if (n == nullptr) return 0;
22 return 1 + max(height(n->getLeft()), height(n->getRight()));
23}
24
25int balanceFactor(Node* n) { // Balancefaktor: linke Höhe minus rechte Höhe
26 return height(n->getLeft()) - height(n->getRight());
27}
28
29Node* rotateRight(Node* y) { // Einfache Rechtsrotation: das linke Kind x steigt auf und y steigt ab
30 Node* x = y->getLeft();
31 y->setLeft(x->getRight());
32 x->setRight(y);
33 return x;
34}
35
36Node* rotateLeft(Node* x) { // Einfache Linksrotation: das rechte Kind y steigt auf und x steigt ab
37 Node* y = x->getRight();
38 x->setRight(y->getLeft());
39 y->setLeft(x);
40 return y;
41}
42
43Node* rebalance(Node* n) { // Gibt die Wurzel des Teilbaums zurück, balanciert
44 int bf = balanceFactor(n); // Der Balancefaktor des Knotens wird berechnet
45 if (bf > 1) { // Linkslastig. Ist das linke Kind nicht rechtslastig, liegt der LL-Fall vor
46 if (balanceFactor(n->getLeft()) < 0) // Das linke Kind ist rechtslastig: LR-Fall, zuerst links rotieren
47 n->setLeft(rotateLeft(n->getLeft())); // Erste Rotation des LR-Falls
48 return rotateRight(n); // Rechtsrotation: löst LL und die zweite Hälfte von LR
49 }
50 if (bf < -1) { // Rechtslastig. Ist das rechte Kind nicht linkslastig, liegt der RR-Fall vor
51 if (balanceFactor(n->getRight()) > 0) // Das rechte Kind ist linkslastig: RL-Fall, zuerst rechts rotieren
52 n->setRight(rotateRight(n->getRight())); // Erste Rotation des RL-Falls
53 return rotateLeft(n); // Linksrotation: löst RR und die zweite Hälfte von RL
54 }
55 return n; // Der Faktor liegt zwischen -1 und 1: keine Rotation nötig
56}
57
58Node* insert(Node* root, int v) { // Fügt v in den AVL-Baum ein und gibt die Wurzel zurück
59 if (root == nullptr) // Freie Stelle: hier kommt der neue Knoten hin
60 return new Node(v); // Erzeugt den neuen Knoten
61 if (v < root->getValue()) // Kleinere Werte gehen nach links, größere nach rechts
62 root->setLeft(insert(root->getLeft(), v)); // Steigt in den linken Teilbaum ab
63 else
64 root->setRight(insert(root->getRight(), v)); // Steigt in den rechten Teilbaum ab
65 return rebalance(root); // Beim Rückweg aus jedem Aufruf wird die Balance des Knotens geprüft
66}
67
68int main() {
69 Node* root = buildTree(); // Der angezeigte Baum, bereits aufgebaut
70 root = insert(root, v); // Erster Aufruf, aus main
71 return 0; // Ende der Operation
72}