Advertisement
faunuss

Untitled

Nov 20th, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.14 KB | None | 0 0
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. #pragma region AVL
  5. struct Node { //Структура узла дерева, хранящий указатели на правое и левое поддерево + высоту
  6.     int key;
  7.     unsigned char height; //высота поддерева с корнем в данном узле
  8.     Node* left; //Указатель на левое поддерево
  9.     Node* right; //Указатель на правое поддерево
  10.     Node(int k) : key(k), left(NULL), right(NULL), height(1) {} //Конструктор
  11. };
  12.  
  13. class CAVLtree
  14. {
  15. public:
  16.     Node* root; //Корень дерева
  17.  
  18.     CAVLtree() //Конструктор
  19.     {
  20.         root = NULL;
  21.     }
  22.     ~CAVLtree() //Деструктор. НАПИСАТЬ!
  23.     {
  24.  
  25.     }
  26.  
  27.     int Insert(int key) //Вставка элемента
  28.     {
  29.         int num = 0;
  30.         int BigNum = 0;
  31.         root = insert(root, key);
  32.         bool flag = false;
  33.         InOrder(root, key, num, flag, BigNum);
  34.         return BigNum;
  35.     }
  36.     void remove(int pos)
  37.     {
  38.         int num = 0;
  39.         bool flag = false;
  40.         Node* tmp = new Node(0);
  41.         DelInOrder(root, num, pos, flag, tmp);
  42.  
  43.         root = remove(root, tmp->key);
  44.     }
  45. private:
  46.     //Три вспомогательные функции, связанные с высотой
  47.     unsigned char Height(Node* node) //Возвращает высоту дерева или 0 - если дерево пустое
  48.     {
  49.         if (node != NULL)
  50.         {
  51.             return node->height;
  52.         }
  53.         return 0;
  54.     }
  55.     int BalanceFactor(Node* node) { //Вычисляет balance factor для заданного узла
  56.         return(Height(node->right) - Height(node->left)); // разница высоту правого поддерева и левого
  57.     }
  58.     void RebuildHeight(Node* node) { //Восстанавливает корректное значение высоты в данном узле
  59.         unsigned char LeftHeight = Height(node->left);
  60.         unsigned char RightHeight = Height(node->right);
  61.         if (LeftHeight > RightHeight) {
  62.             node->height = LeftHeight + 1;
  63.         }
  64.         else
  65.         {
  66.             node->height = RightHeight + 1;
  67.         }
  68.     }
  69.     //Повороты
  70.     void RotateLeft(Node*& node) //Левое вращение
  71.     {
  72.         Node* tmp = node->right;
  73.         node->right = tmp->left;
  74.         tmp->left = node;
  75.         RebuildHeight(node);
  76.         RebuildHeight(tmp);
  77.         node = tmp;
  78.     }
  79.     void RotateRight(Node*& node) //Правое вращение
  80.     {
  81.         Node* tmp = node->left;
  82.         node->left = tmp->right;
  83.         tmp->right = node;
  84.         RebuildHeight(node);
  85.         RebuildHeight(tmp);
  86.         node = tmp;
  87.     }
  88.     //Балансировка
  89.     void balance(Node*& node) { //балансировка узла
  90.         RebuildHeight(node);
  91.         if (BalanceFactor(node) == 2) { //если равен двум
  92.             if (BalanceFactor(node->right) < 0)
  93.             {
  94.                 RotateRight(node->right);
  95.             }
  96.             RotateLeft(node);
  97.         }
  98.         if (BalanceFactor(node) == -2) //если равен МИНУС двум
  99.         {
  100.             if (BalanceFactor(node->left) > 0)
  101.             {
  102.                 RotateLeft(node->left);
  103.             }
  104.             RotateRight(node);
  105.         }
  106.         return; // балансировка не нужна
  107.     }
  108.     //Вставка
  109.     Node* insert(Node* node, int key)
  110.     {
  111.  
  112.         if (node == NULL)
  113.         {
  114.             return new Node(key);
  115.         }
  116.         if (key < node->key) {
  117.             node->left = insert(node->left, key);
  118.         }
  119.         else
  120.         {
  121.             node->right = insert(node->right, key);
  122.         }
  123.         balance(node);
  124.  
  125.         return node;
  126.     }
  127.     void InOrder(Node* node, int key, int& num, bool& flag, int& BigNum)
  128.     {
  129.         if (flag == true)
  130.         {
  131.             return;
  132.         }
  133.         if (node == NULL)
  134.         {
  135.             return;
  136.         }
  137.  
  138.         InOrder(node->right, key, num, flag, BigNum);
  139.         if (node->key == key)
  140.         {
  141.             flag = true;
  142.             BigNum = num;
  143.             return;
  144.         }
  145.         num++;
  146.         InOrder(node->left, key, num, flag, BigNum);
  147.     }
  148.     //Удаление
  149.     Node* FindMin(Node* node)
  150.     {
  151.         if (node->left != NULL)
  152.         {
  153.             return FindMin(node->left);
  154.         }
  155.         return node;
  156.     }
  157.     Node* DeleteMin(Node* node)
  158.     {
  159.         if (node->left == NULL)
  160.         {
  161.             return node->right;
  162.         }
  163.         node->left = DeleteMin(node->left);
  164.         balance(node);
  165.         return node;
  166.     }
  167.     Node* remove(Node* node, int key)
  168.     {
  169.         if (node == NULL)
  170.         {
  171.             return 0;
  172.         }
  173.         if (key < node->key)
  174.         {
  175.             node->left = remove(node->left, key);
  176.         }
  177.         else if(key>node->key)
  178.         {
  179.             node->right = remove(node->right, key);
  180.         }
  181.         else
  182.         {
  183.             Node* left = node->left;
  184.             Node* right = node->right;
  185.             delete node;
  186.             if (right == NULL)
  187.             {
  188.                 return left;
  189.             }
  190.             Node* min = FindMin(right);
  191.             min->right = DeleteMin(right);
  192.             min->left = left;
  193.             balance(min);
  194.             return min;
  195.         }
  196.         balance(node);
  197.         return node;
  198.     }
  199.     void DelInOrder(Node* node, int& num, int& pos, bool& flag, Node*& tmp)
  200.     {
  201.         if (node == NULL)
  202.         {
  203.             return;
  204.         }
  205.         if (flag == true)
  206.         {
  207.             return;
  208.         }
  209.         DelInOrder(node->right, num, pos, flag, tmp);
  210.         if (num == pos)
  211.         {
  212.             flag = true;
  213.             tmp = node;
  214.         }
  215.         num++;
  216.         DelInOrder(node->left, num, pos, flag, tmp);
  217.     }
  218. };
  219.  
  220. #pragma endregion
  221.  
  222. int main()
  223. {
  224.  
  225.     int N = 0;
  226.     cin >> N;
  227.     CAVLtree AVL;
  228.  
  229.     for (int i = 0; i < N; i++) {
  230.         int command = 0; int number = 0;
  231.         cin >> command;
  232.         cin >> number;
  233.         if (command == 1) {
  234.             cout << AVL.Insert(number);
  235.             cout << " ";
  236.         }
  237.         if (command == 2) {
  238.             AVL.remove(number);
  239.         }
  240.     }
  241.     return 0;
  242. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement