Сделать балансировку дерева

#include <iostream>

using namespace std;

typedef int T;

struct Tree{
  T Data;
  Tree *Left;
  Tree *Right;
  Tree *Parent;
};

Tree *root = NULL;

Tree *insertTree(T Data) {
    Tree *x, *current, *parent;
    current = root;
    parent = 0;
    while (current) {
        if (Data == current->Data) return (current);
        parent = current;
        current = Data < current->Data ? current -> Left : current -> Right;
    }
    x = new Tree;
    x -> Data = Data;
    x -> Parent = parent;
    x -> Left = NULL; x -> Right = NULL;
    if (parent)
        if ( x->Data < parent -> Data)
            parent->Left = x;
        else
            parent->Right = x;
    else
        root = x;
    return(x);
}

void PrintTree(Tree *tree, int l){
    int i;
    if (tree != NULL) {
        PrintTree(tree->Right, l+1);
        for (i = 0; i < l; i++) cout << "   ";
        cout << "   " << tree -> Data;
        PrintTree(tree->Left, l+1);
    }
    else cout << endl;
}

Tree *FindTree(T data) {
    Tree *current = root;
    while (current != NULL)
        if (data = current->Data)
            return(current);
        else
            current = (data < current->Data) ? current->Left : current->Right;
    return(current);
}

void deleteTree(Tree *z) {
    Tree *x, *y;
    if (!z || z == NULL) return;
    if (z->Left != NULL || z->Right == NULL)
        y=z;
    else {
        y=z->Right;
        while (y->Left !=NULL) y= y->Left;
    }
    if (y->Left !=NULL)
      x=y->Left;
    else
      x=y->Right;
    if (x) x->Parent = y->Parent;
    if (y -> Parent) 
        if (y == y -> Parent->Left)
            y->Parent->Left = x;
        else
            y->Parent->Right = x;
    else
        root = x;
    if (y != z) {
        y->Left = z->Left;
        if (y->Left) y->Left->Parent = y;
            y->Right = z->Right;
        if (y->Right) y->Right->Parent = y;
            y->Parent = z->Parent;
        if (z->Parent)
            if (z == z->Parent->Left)
                z->Parent->Left = y;
            else
                z->Parent->Right = y;
        else
            root = y;
            delete z;
    }
    else {
        delete y;
    }
}

int main()
{
    int i, *a, maxnum;
    cout << "Введите количество элементов maxnum: ";
    cin >> maxnum;
    cout << endl;
        a = new int[maxnum];
        srand (time(NULL)*10);
    // генерация массива
    for (i = 0; i < maxnum; i++)
        a[i] = rand() % 20-10;
    cout << "Вывод сгенерированной последовательности: " << endl;
    for (i = 0; i < maxnum; i++)
        cout << a[i] << "   ";
    cout << endl << endl;
    // добавление элементов в дерево
    for (i = 0; i < maxnum; i++)
        insertTree(a[i]);
    cout << "Вывод дерева: " << endl;
    Tree *new_root = root;
    PrintTree(root, 0);
    cout << endl;
    // вырезаем масленка
    deleteTree(FindTree(5));
    cout << "Вывод нового дерева:" << endl;
    PrintTree(new_root, 0);
    
}

Что именно не получается?
В гугле ж полно материалов и примеров. Только надо определиться как именно балансировать: при каждой вставке или периодически/один раз.

Вообще надо бы при каждой вставке делать.