Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- using namespace std;
- #pragma region AVL
- struct Node { //Структура узла дерева, хранящий указатели на правое и левое поддерево + высоту
- int key;
- unsigned char height; //высота поддерева с корнем в данном узле
- Node* left; //Указатель на левое поддерево
- Node* right; //Указатель на правое поддерево
- Node(int k) : key(k), left(NULL), right(NULL), height(1) {} //Конструктор
- };
- class CAVLtree
- {
- public:
- Node* root; //Корень дерева
- CAVLtree() //Конструктор
- {
- root = NULL;
- }
- ~CAVLtree() //Деструктор. НАПИСАТЬ!
- {
- }
- int Insert(int key) //Вставка элемента
- {
- int num = 0;
- int BigNum = 0;
- root = insert(root, key);
- bool flag = false;
- InOrder(root, key, num, flag, BigNum);
- return BigNum;
- }
- void remove(int pos)
- {
- int num = 0;
- bool flag = false;
- Node* tmp = new Node(0);
- DelInOrder(root, num, pos, flag, tmp);
- root = remove(root, tmp->key);
- }
- private:
- //Три вспомогательные функции, связанные с высотой
- unsigned char Height(Node* node) //Возвращает высоту дерева или 0 - если дерево пустое
- {
- if (node != NULL)
- {
- return node->height;
- }
- return 0;
- }
- int BalanceFactor(Node* node) { //Вычисляет balance factor для заданного узла
- return(Height(node->right) - Height(node->left)); // разница высоту правого поддерева и левого
- }
- void RebuildHeight(Node* node) { //Восстанавливает корректное значение высоты в данном узле
- unsigned char LeftHeight = Height(node->left);
- unsigned char RightHeight = Height(node->right);
- if (LeftHeight > RightHeight) {
- node->height = LeftHeight + 1;
- }
- else
- {
- node->height = RightHeight + 1;
- }
- }
- //Повороты
- void RotateLeft(Node*& node) //Левое вращение
- {
- Node* tmp = node->right;
- node->right = tmp->left;
- tmp->left = node;
- RebuildHeight(node);
- RebuildHeight(tmp);
- node = tmp;
- }
- void RotateRight(Node*& node) //Правое вращение
- {
- Node* tmp = node->left;
- node->left = tmp->right;
- tmp->right = node;
- RebuildHeight(node);
- RebuildHeight(tmp);
- node = tmp;
- }
- //Балансировка
- void balance(Node*& node) { //балансировка узла
- RebuildHeight(node);
- if (BalanceFactor(node) == 2) { //если равен двум
- if (BalanceFactor(node->right) < 0)
- {
- RotateRight(node->right);
- }
- RotateLeft(node);
- }
- if (BalanceFactor(node) == -2) //если равен МИНУС двум
- {
- if (BalanceFactor(node->left) > 0)
- {
- RotateLeft(node->left);
- }
- RotateRight(node);
- }
- return; // балансировка не нужна
- }
- //Вставка
- Node* insert(Node* node, int key)
- {
- if (node == NULL)
- {
- return new Node(key);
- }
- if (key < node->key) {
- node->left = insert(node->left, key);
- }
- else
- {
- node->right = insert(node->right, key);
- }
- balance(node);
- return node;
- }
- void InOrder(Node* node, int key, int& num, bool& flag, int& BigNum)
- {
- if (flag == true)
- {
- return;
- }
- if (node == NULL)
- {
- return;
- }
- InOrder(node->right, key, num, flag, BigNum);
- if (node->key == key)
- {
- flag = true;
- BigNum = num;
- return;
- }
- num++;
- InOrder(node->left, key, num, flag, BigNum);
- }
- //Удаление
- Node* FindMin(Node* node)
- {
- if (node->left != NULL)
- {
- return FindMin(node->left);
- }
- return node;
- }
- Node* DeleteMin(Node* node)
- {
- if (node->left == NULL)
- {
- return node->right;
- }
- node->left = DeleteMin(node->left);
- balance(node);
- return node;
- }
- Node* remove(Node* node, int key)
- {
- if (node == NULL)
- {
- return 0;
- }
- if (key < node->key)
- {
- node->left = remove(node->left, key);
- }
- else if(key>node->key)
- {
- node->right = remove(node->right, key);
- }
- else
- {
- Node* left = node->left;
- Node* right = node->right;
- delete node;
- if (right == NULL)
- {
- return left;
- }
- Node* min = FindMin(right);
- min->right = DeleteMin(right);
- min->left = left;
- balance(min);
- return min;
- }
- balance(node);
- return node;
- }
- void DelInOrder(Node* node, int& num, int& pos, bool& flag, Node*& tmp)
- {
- if (node == NULL)
- {
- return;
- }
- if (flag == true)
- {
- return;
- }
- DelInOrder(node->right, num, pos, flag, tmp);
- if (num == pos)
- {
- flag = true;
- tmp = node;
- }
- num++;
- DelInOrder(node->left, num, pos, flag, tmp);
- }
- };
- #pragma endregion
- int main()
- {
- int N = 0;
- cin >> N;
- CAVLtree AVL;
- for (int i = 0; i < N; i++) {
- int command = 0; int number = 0;
- cin >> command;
- cin >> number;
- if (command == 1) {
- cout << AVL.Insert(number);
- cout << " ";
- }
- if (command == 2) {
- AVL.remove(number);
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement