Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // main.cpp
- // 3_2
- //
- // Created by Артем Ямалутдинов on 12.11.17.
- // Copyright © 2017 Артем Ямалутдинов. All rights reserved.
- //
- #include <iostream>
- struct CNode;
- using AVLTree = CNode*;
- struct CNode {
- CNode (int key): key(key), size(1), height(1), left(nullptr), right(nullptr) {}
- int key;
- int size; //Суммарный размер поддерева
- int height; //Высота поддерева
- AVLTree left;
- AVLTree right;
- };
- int height (AVLTree tree) {
- return tree ? tree->height : 0;
- }
- int balanceFactor(AVLTree tree) {
- return height(tree->right) - height(tree->left);
- }
- int fixSize(AVLTree tree) { //Восстанавливает значение размера поддерева
- if (!tree) {
- return 0;
- }
- if (tree->left && tree->right) {
- return tree->left->size + tree->right->size + 1;
- }
- else if (tree->left || tree->right) {
- return tree->left ? tree->left->size + 1 : tree->right->size + 1;
- }
- else {
- return 1;
- }
- }
- void fixHeight(AVLTree tree) { //Восстанавливает значение высоты поддерева
- int h_left = height(tree->left);
- int h_right = height(tree->right);
- tree->height = (h_left > h_right ? h_left : h_right) + 1;
- tree->size = fixSize(tree);
- }
- AVLTree rotateLeft (AVLTree tree) { //Малое левое вращение
- AVLTree rightTree = tree->right;
- tree->right = rightTree->left;
- rightTree->left = tree;
- fixHeight(tree);
- fixHeight(rightTree);
- return rightTree;
- }
- AVLTree rotateRight (AVLTree tree) { //Малое правое вращение
- AVLTree leftTree = tree->left;
- tree->left = leftTree->right;
- leftTree->right = tree;
- fixHeight(tree);
- fixHeight(leftTree);
- return leftTree;
- }
- AVLTree balanceTree (AVLTree tree) { //Балансировка дерева
- fixHeight(tree);
- if (balanceFactor(tree) == 2) {
- if (balanceFactor(tree->right) < 0) {
- tree->right = rotateRight(tree->right);
- }
- return rotateLeft(tree);
- }
- if (balanceFactor(tree) == -2) {
- if (balanceFactor(tree->left) > 0) {
- tree->left = rotateLeft(tree->left);
- }
- return rotateRight(tree);
- }
- return tree;
- }
- AVLTree insert (AVLTree tree, int key) {
- if (!tree) {
- return new CNode(key);
- }
- if (key < tree->key) {
- tree->left = insert(tree->left, key);
- }
- else {
- tree->right = insert(tree->right, key);
- }
- return balanceTree(tree);
- }
- AVLTree findMin (AVLTree tree) { //Поиск минимального элемента в данном поддереве
- return tree->left ? findMin(tree -> left) : tree;
- }
- AVLTree removeMin (AVLTree tree) {
- if (tree->left == nullptr) {
- return tree->right;
- }
- tree->left = removeMin(tree->left);
- return balanceTree(tree);
- }
- AVLTree remove (AVLTree tree, int key) {
- if (!tree) {
- return nullptr;
- }
- if (tree->key > key) {
- tree->left = remove(tree->left, key);
- }
- else if (tree->key < key) {
- tree->right = remove(tree->right, key);
- }
- else {
- AVLTree leftTree = tree->left;
- AVLTree rightTree = tree->right;
- delete tree;
- if (!rightTree) {
- return leftTree;
- }
- AVLTree min = findMin(rightTree);
- min->right = removeMin(rightTree);
- min->left = leftTree;
- return balanceTree(min);
- }
- return balanceTree(tree);
- }
- int getKStat(AVLTree tree, int k) {
- AVLTree tmp_tree = tree;
- while (tmp_tree) {
- if (fixSize(tmp_tree->left) == k) {
- return tmp_tree->key;
- }
- else if (fixSize(tmp_tree->left) > k) {
- tmp_tree = tmp_tree->left;
- }
- else {
- k -= (fixSize(tmp_tree->left) + 1);
- tmp_tree = tmp_tree->right;
- }
- }
- return -1;
- }
- void deleteTree (AVLTree tree) {
- if (!tree) {
- return;
- }
- deleteTree(tree->left);
- deleteTree(tree->right);
- delete tree;
- }
- int main() {
- int count = 0;
- std::cin >> count;
- int key = 0, kStat = 0;
- AVLTree tree = nullptr;
- for (int i = 0; i < count; ++i) {
- std::cin >> key >> kStat;
- if (key >= 0) {
- tree = insert(tree, key);
- }
- else {
- key *= -1;
- tree = remove(tree, key);
- }
- std::cout << getKStat(tree, kStat) << std::endl;
- }
- deleteTree(tree);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement