Advertisement
Guest User

Untitled

a guest
Nov 18th, 2017
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.51 KB | None | 0 0
  1. #include <iostream>
  2. #include <cassert>
  3. #include <queue>
  4. #include <vector>
  5. #include <string>
  6.  
  7. struct CNode // структура для представления узлов дерева
  8. {
  9.     int key;
  10.     int height;
  11.     int count;
  12.     CNode* left;
  13.     CNode* right;
  14.     CNode() : left(nullptr), right(nullptr), height(0), key(0) {}
  15. };
  16.  
  17. class avlTree {
  18. public:
  19.     ~avlTree();
  20.     avlTree() : root(nullptr) {};
  21.     int height(CNode* p);
  22.     int count(CNode* p);
  23.     int bfactor(CNode* p);
  24.     void fixheight(CNode* p);
  25.     void fixcount(CNode* p);
  26.     bool add(int k);
  27.     bool deletekey(int k);
  28.     void Show();
  29.     void printAsTree(CNode* node, int currentLevel);
  30.     int findplace(CNode* p, int k);
  31.     CNode* rotateright(CNode* p);
  32.     CNode* rotateleft(CNode* q);
  33.     CNode* balance(CNode* p);
  34.     CNode* insert(CNode* p, int k);
  35.     std::pair<CNode*, CNode*> removemin(CNode* p);
  36.     CNode* remove(CNode* p, int k);
  37.     CNode* getroot();
  38.     int findstat(CNode* current, int y);
  39.     void DestroyTree(CNode* node);
  40. private:
  41.     CNode* root;
  42. };
  43.  
  44. avlTree::~avlTree() {
  45.     DestroyTree(root);
  46. }
  47.  
  48. void avlTree::DestroyTree(CNode* node) {
  49.     if (node == nullptr) {
  50.         return;
  51.     }
  52.     DestroyTree(node->left);
  53.     node->left = nullptr;
  54.     DestroyTree(node->right);
  55.     node->right = nullptr;
  56.     delete node;
  57. }
  58.  
  59. CNode* avlTree::getroot() {
  60.     return root;
  61. }
  62.  
  63. int avlTree::height(CNode* p)
  64. {
  65.     return p ? p->height : 0;
  66. }
  67.  
  68. int avlTree::count(CNode* p)
  69. {
  70.     return p ? p->count : 0;
  71. }
  72.  
  73. int avlTree::bfactor(CNode* p) //разность высот
  74. {
  75.     return height(p->right) - height(p->left);
  76. }
  77.  
  78. void avlTree::fixheight(CNode* p) // восстановление  height
  79. {
  80.     int hl = height(p->left);
  81.     int hr = height(p->right);
  82.     p->height = (hl>hr ? hl : hr) + 1;
  83. }
  84.  
  85. void avlTree::fixcount(CNode* p) //восстановление count
  86. {
  87.     int hl = count(p->left);
  88.     int hr = count(p->right);
  89.     p->count = hl + hr + 1;
  90. }
  91.  
  92. CNode* avlTree::rotateright(CNode* p) // правый поворот вокруг p
  93. {
  94.     CNode* q = p->left;
  95.     p->left = q->right;
  96.     q->right = p;
  97.     fixheight(p);
  98.     fixheight(q);
  99.     fixcount(p);
  100.     fixcount(q);
  101.     return q;
  102. }
  103.  
  104. CNode* avlTree::rotateleft(CNode* q) // левый поворот вокруг q
  105. {
  106.     CNode* p = q->right;
  107.     q->right = p->left;
  108.     p->left = q;
  109.     fixheight(q);
  110.     fixheight(p);
  111.     fixcount(q);
  112.     fixcount(p);
  113.     return p;
  114. }
  115.  
  116. CNode* avlTree::balance(CNode* p) // балансировка узла p
  117. {
  118.     fixheight(p);
  119.     fixcount(p);
  120.     if (bfactor(p) == 2)
  121.     {
  122.         if (bfactor(p->right) < 0)
  123.             p->right = rotateright(p->right);
  124.         return rotateleft(p);
  125.     }
  126.     if (bfactor(p) == -2)
  127.     {
  128.         if (bfactor(p->left) > 0)
  129.             p->left = rotateleft(p->left);
  130.         return rotateright(p);
  131.     }
  132.     return p; // балансировка не нужна
  133. }
  134.  
  135. bool avlTree::add(int k) { //добавление ключа в дерево
  136.     root = insert(root, k);
  137.     return true;
  138. }
  139.  
  140. int avlTree::findplace(CNode* p, int k) // нахождение номера элемента по ключу
  141. {
  142.     if (p == nullptr) {
  143.         return 0;
  144.     }
  145.     if (k > p->key)
  146.         return findplace(p->right, k);
  147.     else
  148.         return findplace(p->left, k) + count(p->right) + 1;
  149. }
  150.        
  151. CNode* avlTree::insert(CNode* p, int k) // вставка ключа k в дерево с корнем p
  152. {
  153.     if (p == nullptr) {
  154.         CNode* newNode = new CNode();
  155.         newNode->key = k;
  156.         newNode->height = 1;
  157.         newNode->count = 1;
  158.         return newNode;
  159.     }
  160.     if (k < p->key) {
  161.         p->left = insert(p->left, k);
  162.     }
  163.     else {
  164.         p->right = insert(p->right, k);
  165.     }
  166.     return balance(p);
  167. }
  168.  
  169. std::pair<CNode*, CNode*> avlTree::removemin(CNode* p) // удаление узла с минимальным ключом из дерева p
  170. {
  171.     if (p->left == 0)
  172.         return std::make_pair(p->right, p);
  173.     std::pair<CNode*, CNode*> answer = removemin(p->left);
  174.     p->left = answer.first;
  175.     return std::make_pair(balance(p), answer.second);
  176. }
  177.  
  178. bool avlTree::deletekey(int k) {
  179.     root = remove(root, k);
  180.     return true;
  181. }
  182.  
  183. CNode* avlTree::remove(CNode* p, int k) // удаление ключа k из дерева p
  184. {
  185.     if (p == nullptr) return nullptr;
  186.     if (k < p->key)
  187.         p->left = remove(p->left, k);
  188.     else if (k > p->key)
  189.         p->right = remove(p->right, k);
  190.     else
  191.     {
  192.         CNode* q = p->left;
  193.         CNode* r = p->right;
  194.         delete p;
  195.         if (!r) return q;
  196.         std::pair<CNode*, CNode*> subtree = removemin(r);
  197.         CNode* min = subtree.second;
  198.         min->left = q;
  199.         min->right = subtree.first;
  200.         return balance(min);
  201.     }
  202.     return balance(p);
  203. }
  204.  
  205. int avlTree::findstat(CNode* current, int y) {
  206.     if (count(current->right) == y) {
  207.         return current->key;
  208.     } else if (count(current->right) < y) {
  209.         return findstat(current->left, y - count(current->right) - 1);
  210.     } else if (count(current->right) > y) {
  211.         return findstat(current->right, y);
  212.     }
  213. }
  214.  
  215. void avlTree::Show() {
  216.     printAsTree(root, 0);
  217. }
  218.  
  219. void avlTree::printAsTree(CNode* node, int currentLevel) { // Делает обход дерева слева-направо и печатает в консоль дерево, положенное на бок.
  220.     if (node == 0) {
  221.         return;
  222.     }
  223.     printAsTree(node->left, currentLevel + 1);
  224.     std::cout << std::string(currentLevel, '\t') << "(" << node->key << ' ' << node->height << ' ' << node->count << ")" << std::endl;
  225.     printAsTree(node->right, currentLevel + 1);
  226. }
  227.  
  228. int main() {
  229.    
  230.     avlTree tree;
  231.     int n, k, m;
  232.     std::cin >> n;
  233.     for (int i = 0; i < n; ++i) {
  234.         std::cin >> k >> m;
  235.         if (k == 1) {
  236.             tree.add(m);
  237.             std::cout << tree.findplace(tree.getroot(), m) - 1 << ' ' ;
  238.         }
  239.         if (k == 2) {
  240.             tree.deletekey(tree.findstat(tree.getroot(), m));
  241.         }
  242.     }
  243.     return 0;
  244. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement