Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- int result = -1;
- class node
- {
- public:
- int key, height; // Key and height of the node
- // Every node has only one left and right child (if they exist of course)
- node *left_child;
- node *right_child;
- // Constructor
- node () {}
- node(int key, int height)
- {
- this -> key = key;
- this -> height = height;
- }
- // Make new node with given value
- node* new_node(int val)
- {
- // Allocate memory for new node
- node* x = (node*)malloc(sizeof(struct node));
- x->key = val;
- x->left_child = NULL;
- x->right_child = NULL;
- x->height = 1; // Currently a leaf
- // Return the new node
- return x;
- }
- };
- // Helper function to return the height at which the node x is
- int get_height(node *x)
- {
- if (x == NULL) { // Empty
- return 0;
- }
- return x->height;
- }
- // Return the predecessor of the current node
- node* get_predecessor(node *current)
- {
- node* x = current;
- while (x->right_child != NULL)
- {
- x = x->right_child;
- }
- return x;
- }
- // Return the successor of the current node
- node* get_successor(node *current)
- {
- node* x = current;
- while (x->left_child != NULL)
- {
- x = x->left_child;
- }
- return x;
- }
- node* right_rotate(node *current)
- {
- node *child = current->left_child;
- node *subtree = child->right_child;
- // Rotate (i.e. change places)
- child->right_child = current;
- current->left_child = subtree;
- // Update the height values
- current->height = max(get_height(current->left_child), get_height(current->right_child)) + 1;
- child->height = max(get_height(child->left_child), get_height(child->right_child)) + 1;
- return child;
- }
- node* left_rotate(node *current)
- {
- node *child = current->right_child;
- node *subtree = child->left_child;
- // Rotate
- child->left_child = current;
- current->right_child = subtree;
- // Update height values
- current->height = max(get_height(current->left_child), get_height(current->right_child)) + 1;
- child->height = max(get_height(child->left_child), get_height(child->right_child)) + 1;
- return child;
- }
- // Delete the node in the BST with value = key
- node* delete_node(node* parent, int key)
- {
- if (parent == NULL) {
- return parent;
- }
- // Continue on right subtree
- if (key > parent->key) {
- delete_node(parent->right_child, key);
- }
- // Continue on left subtree
- else if (key < parent->key) {
- delete_node(parent->left_child, key);
- }
- // If the key is the same as the value of the current node, then this is the wanted node
- else {
- // Only one or no child
- if (parent->left_child == NULL or parent->right_child == NULL)
- {
- node* child;
- if (parent->right_child != NULL) {
- child = parent->right_child;
- } else {
- child = parent->left_child;
- }
- // No child
- if (child == NULL)
- {
- child = parent;
- parent = NULL;
- }
- else // One child: copy the contents (key, height etc)
- {
- *parent = *child;
- }
- }
- // Two children
- else
- {
- node* new_parent = get_predecessor(parent->left_child);
- parent->key = new_parent->key; // Copy only the new key
- // Delete the predecessor since it's been replaced
- parent->left_child = delete_node(parent->left_child, new_parent->key);
- }
- }
- // Get height of the node
- parent->height = max(get_height(parent->left_child), get_height(parent->right_child)) + 1;
- int state;
- if (parent == NULL) {
- state = 0;
- }
- else {
- state = get_height(parent->left_child) - get_height(parent->right_child);
- }
- // 1.1. Left child of parent is left-weighted
- if (state > 1 and key < parent->left_child->key)
- {
- return right_rotate(parent);
- }
- // 1.2 Left child of parent is right-weighted
- if (state > 1 and key > parent->left_child->key)
- {
- parent->left_child = left_rotate(parent->left_child);
- return right_rotate(parent);
- }
- // 2.1. Right child of parent is right-weighted
- if (state < -1 and key > parent->right_child->key)
- {
- return left_rotate(parent);
- }
- // 2.2. Right child of parent is left-weighted
- if (state < -1 and key < parent->right_child->key)
- {
- parent->right_child = right_rotate(parent->right_child);
- return left_rotate(parent);
- }
- return parent;
- }
- // parent is the previous node and key is the value of the element that should be inserted
- node* insert_node(node* parent, int key)
- {
- if (parent == NULL) {
- return node().new_node(key);
- }
- // Decide where to continue with recursion
- if (key < parent->key) {
- parent->left_child = insert_node(parent->left_child, key);
- }
- else if (key > parent->key) {
- parent->right_child = insert_node(parent->right_child, key);
- }
- else {
- return parent;
- }
- // Height of a parent is the bigger height of the two children plus 1
- parent->height = max(get_height(parent->left_child), get_height(parent->right_child)) + 1;
- int state;
- if (parent == NULL) {
- state = 0;
- }
- else {
- state = get_height(parent->left_child) - get_height(parent->right_child);
- }
- // 1.1. Left child of parent is left-weighted
- if (state > 1 and key < parent->left_child->key)
- {
- return right_rotate(parent);
- }
- // 1.2 Left child of parent is right-weighted
- if (state > 1 and key > parent->left_child->key)
- {
- parent->left_child = left_rotate(parent->left_child);
- return right_rotate(parent);
- }
- // 2.1. Right child of parent is right-weighted
- if (state < -1 and key > parent->right_child->key)
- {
- return left_rotate(parent);
- }
- // 2.2. Right child of parent is left-weighted
- if (state < -1 and key < parent->right_child->key)
- {
- parent->right_child = right_rotate(parent->right_child);
- return left_rotate(parent);
- }
- return parent;
- }
- node* query(node* parent, int key)
- {
- if (parent == NULL) {
- return parent;
- }
- // The node is in the left subtree
- if (key < parent->key)
- {
- query(parent->left_child, key);
- }
- // The node is in the right subtree
- else if (key > parent->key)
- {
- query(parent->right_child, key);
- }
- else // The needed node is this
- {
- // Return it's predecessor
- node *predecessor = get_predecessor(parent->left_child);
- result = predecessor->key;
- return predecessor;
- }
- return parent;
- }
- int main(void)
- {
- ios::sync_with_stdio(false);
- cin.tie(0); cout.tie(0);
- int tasks;
- node *root = NULL; // The root of the AVL tree
- cin >> tasks;
- while (tasks--)
- {
- int type, number;
- cin >> type >> number;
- if (type == 0) { // Print the predecessor of number
- query(root, number);
- cout << result << endl;
- result = -1;
- }
- if (type == 1) { // Insert the current number in the BST
- root = insert_node(root, number);
- }
- if (type == 2) { // Delete the current number from the BST
- root = delete_node(root, number);
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment