Теперь есть несколько способов реализовать это; передавая родительский узел, или передавая левый / правый указатель родителя по ссылке, когда вы выбираете левый / правый путь соответственно, или возвращая root текущего поддерева (после балансировки, если это требуется) родителю, как вы двигаемся вверх по дереву.
Я отправлю третий способ, потому что он уменьшает размер кода.
int getHeight(Node *current) { return current == nullptr ? -1 : current->height; }
int getBalanceFactor(Node *current) { return getHeight(current->left) - getHeight(current->right); }
Node* rightRotate(Node *y)
{
Node *x = y->left;
y->left = x->right;
x->right = y;
y->height = max(getHeight(y->left), getHeight(y->right)) + 1;
x->height = max(getHeight(x->left), getHeight(x->right)) + 1;
return x;
}
Node* leftRotate(Node *x)
{
Node *y = x->right;
x->right = y->left;
y->left = x;
x->height = max(getHeight(x->left), getHeight(x->right)) + 1;
y->height = max(getHeight(y->left), getHeight(y->right)) + 1;
return y;
}
Node* insert(Node *current, int key)
{
if (current == nullptr)
return new Node(key);
if (key <= current->key)
current->left = insert(current->left, key);
else
current->right = insert(current->right, key);
// the code hereonwards is when the control is returning from the stack, i.e., we are "moving" up the tree essentially
current->height = max(getHeight(current->left), getHeight(current->right)) + 1;
int bf = getBalanceFactor(current);
// there's no imbalance, return the rooted subtree at `current` as it is
if (-1 <= bf && bf <= 1)
return current;
if (bf == 2)
{
int bf_left = getBalanceFactor(current->left);
// LL case
if (bf_left == 1)
return rightRotate(current);
// LR case
else
{
current->left = leftRotate(current->left);
return rightRotate(current);
}
}
else
{
int bf_right = getBalanceFactor(current->right);
// RR case
if (bf_right == -1)
return leftRotate(current);
// RL case
else
{
current->right = rightRotate(current->right);
return leftRotate(current);
}
}
}
И он должен называться как root = insert(root, key)