1#include <iostream>
2#include <algorithm>
3using namespace std;
4
5class Node { // A node holds its value and pointers to its two children
6private: // Private attributes: only the methods touch them
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) { // Height: a leaf is 1 and an empty spot (nullptr) is 0
21 if (n == nullptr) return 0;
22 return 1 + max(height(n->getLeft()), height(n->getRight()));
23}
24
25int balanceFactor(Node* n) { // Balance factor: left height minus right height
26 return height(n->getLeft()) - height(n->getRight());
27}
28
29Node* rotateRight(Node* y) { // Single right rotation: the left child x goes up and y goes down
30 Node* x = y->getLeft();
31 y->setLeft(x->getRight());
32 x->setRight(y);
33 return x;
34}
35
36Node* rotateLeft(Node* x) { // Single left rotation: the right child y goes up and x goes down
37 Node* y = x->getRight();
38 x->setRight(y->getLeft());
39 y->setLeft(x);
40 return y;
41}
42
43Node* rebalance(Node* n) { // Returns the root of the subtree, balanced
44 int bf = balanceFactor(n); // The node's balance factor is computed
45 if (bf > 1) { // Left heavy. If the left child is not right heavy this is the LL case
46 if (balanceFactor(n->getLeft()) < 0) // The left child is right heavy: LR case, rotate left first
47 n->setLeft(rotateLeft(n->getLeft())); // First rotation of the LR case
48 return rotateRight(n); // Right rotation: solves LL and the second half of LR
49 }
50 if (bf < -1) { // Right heavy. If the right child is not left heavy this is the RR case
51 if (balanceFactor(n->getRight()) > 0) // The right child is left heavy: RL case, rotate right first
52 n->setRight(rotateRight(n->getRight())); // First rotation of the RL case
53 return rotateLeft(n); // Left rotation: solves RR and the second half of RL
54 }
55 return n; // The factor is between -1 and 1: no rotation needed
56}
57
58Node* insert(Node* root, int v) { // Inserts v into the AVL tree and returns the root
59 if (root == nullptr) // Empty spot: the new node goes here
60 return new Node(v); // Creates the new node
61 if (v < root->getValue()) // Smaller values go left and larger ones go right
62 root->setLeft(insert(root->getLeft(), v)); // Goes down the left subtree
63 else
64 root->setRight(insert(root->getRight(), v)); // Goes down the right subtree
65 return rebalance(root); // On the way back from each call the node's balance is checked
66}
67
68int main() {
69 Node* root = buildTree(); // The tree shown, already built
70 root = insert(root, v); // First call, from main
71 return 0; // End of the operation
72}