// An AVL tree node // tao cay avl
struct Node
{
int key;
struct Node *left;
struct Node *right;
int height; // do cao cua cay
};
// A utility function to get maximum of two integers
int max(int a, int b);
int max(int a, int b)
{
return (a > b) ? a : b;
}
// A utility function to get height of the tree
int height(Node *N)
{
if (N == 0)
return 0;
return N->height;
}
// A utility function to get maximum of two integers
// creat new node // tao nut moi
Node* newNode(int key)
{
Node* node = new Node;
node->key = key;
node->left = 0;
node->right = 0;
node->height = 1; // new node is initially added at leaf
return(node);
}
// Get Balance factor of node N // tinh balance
int getBalance(Node *N)
{
if (N == 0)
return 0;
return height(N->left) - height(N->right);
}
Node* insert(Node* node, int key)
{
// like binary search tree common // giong nhu trong cay nhi phan thong thuong
if (node == 0)
return(newNode(key));
//Проходим по пути поиска, пока не убедимся, что ключа в дереве нет.
if (key < node->key)
node->left = insert(node->left, key);
else if (key > node->key)
node->right = insert(node->right, key);
else
return node;
// Update height of this ancestor node // ghi nho chieu cao
/*"Отступаем" назад от добавленной вершины к корню. Проверяем в
каждой вершине сбалансированность. Если разность высот поддеревьев
равна 2 – выполняем нужное вращение.
*/
node->height = 1 + max(height(node->left),
height(node->right));
// get balance
int balance = getBalance(node);
// if balance >= 2 || <= -2 use necessary command // neu balance >= 2, <= -2 su dung lenh phu hop
if (balance > 1 && key < node->left->key)
return rightRotate(node);
if (balance < -1 && key > node->right->key)
return leftRotate(node);
Node * minValueNode(Node* node)
{
Node* current = node;
while (current->left != 0)
current = current->left;
return current;
}
// delete node with key
Node* deleteNode(Node* root, int key)
{
// like binary search tree common // giong nhu trong cay nhi phan thong thuong
// Ищем вершину D, которую требуется удалить.
if (root == 0)
return root;
if (key < root->key)
root->left = deleteNode(root->left, key);
else if (key > root->key)
root->right = deleteNode(root->right, key);
else
{
// node with only one child or no child
//Если D – лист или D имеет одно поддерево, то удаляем D
if ((root->left == 0) || (root->right == 0))
{
struct Node *temp = root->left ? root->left :
root->right;
// No child case
if (temp == 0)
{
temp = root;
root = 0;
}
else // One child case
*root = *temp; // Copy the contents of the non-empty child
free(temp);
}
else
{
/*Если D имеет два поддерева, то ищем вершину M, следующую по
значению после D. Как в стандартном алгоритме удаления из
дерева поиска. Переносим значение из M в D. Удаляем M.*/
Node* temp = minValueNode(root->right);
// Copy the inorder successor's data to this node
root->key = temp->key;
// Delete the inorder successor
root->right = deleteNode(root->right, temp->key);
}
}
// If the tree had only one node then return
if (root == 0)
return root;