#include "AVLCommand.h" // examples of AVL tree algorithms: // https://tfetimes.com/c-avl-tree/ // https://stackoverflow.com/questions/29866315/class-for-avl-trees-c // http://www.sanfoundry.com/cpp-program-implement-avl-trees/ // AVL explanation: // http://www.btechsmartclass.com/DS/U5_T2.html // combination of geeksforgeeks AVL insert and delete code // written for C // => convert into a C++ class // An AVL tree node struct that is probably useless to me struct Node { // already have a struct inside BST... // maybe no pointers in here... // but then why bother with a struct :/ int key; //struct Node *left; //struct Node *right; int height; }; // constructor: builds an AVL tree from BST tree bst AVLCommands::AVLCommands() { BST bst(); // initialize BST with root null and sized 0 } void AVLCommands::Insert(int key) { // normal BST insertion bst.Insert(key); // update height of ancestor node // geeksforgeeks C: node->height = 1 + max(height(node->left), height(node->right)); // check if the tree is unbalanced by checking // ancestor balance factor // if unbalanced // left-left // right-right // left-right // right-left } // Recursive function to insert key in subtree rooted // with node and returns new root of subtree. struct Node* insert(struct Node* node, int key) { /* 1. Perform the normal BST insertion */ if (node == NULL) return(newNode(key)); if (key < node->key) node->left = insert(node->left, key); else if (key > node->key) node->right = insert(node->right, key); else // Equal keys are not allowed in BST return node; /* 2. Update height of this ancestor node */ node->height = 1 + max(height(node->left), height(node->right)); /* 3. Get the balance factor of this ancestor node to check whether this node became unbalanced */ int balance = getBalance(node); // If this node becomes unbalanced, then // there are 4 cases // Left Left Case if (balance > 1 && key < node->left->key) return rightRotate(node); // Right Right Case if (balance < -1 && key > node->right->key) return leftRotate(node); // Left Right Case if (balance > 1 && key > node->left->key) { node->left = leftRotate(node->left); return rightRotate(node); } // Right Left Case if (balance < -1 && key < node->right->key) { node->right = rightRotate(node->right); return leftRotate(node); } /* return the (unchanged) node pointer */ return node; } // A utility function to get maximum of two integers int max(int a, int b); // A utility function to get height of the tree int height(struct Node *N) { if (N == NULL) return 0; return N->height; } // A utility function to get maximum of two integers int max(int a, int b) { return (a > b)? a : b; } /* Helper function that allocates a new node with the given key and NULL left and right pointers. */ struct Node* newNode(int key) { struct Node* node = (struct Node*) malloc(sizeof(struct Node)); node->key = key; node->left = NULL; node->right = NULL; node->height = 1; // new node is initially added at leaf return(node); } // A utility function to right rotate subtree rooted with y // See the diagram given above. struct Node *rightRotate(struct Node *y) { struct Node *x = y->left; struct Node *T2 = x->right; // Perform rotation x->right = y; y->left = T2; // Update heights y->height = max(height(y->left), height(y->right))+1; x->height = max(height(x->left), height(x->right))+1; // Return new root return x; } // A utility function to left rotate subtree rooted with x // See the diagram given above. struct Node *leftRotate(struct Node *x) { struct Node *y = x->right; struct Node *T2 = y->left; // Perform rotation y->left = x; x->right = T2; // Update heights x->height = max(height(x->left), height(x->right))+1; y->height = max(height(y->left), height(y->right))+1; // Return new root return y; } // Get Balance factor of node N int getBalance(struct Node *N) { if (N == NULL) return 0; return height(N->left) - height(N->right); } /* Given a non-empty binary search tree, return the node with minimum key value found in that tree. Note that the entire tree does not need to be searched. */ struct Node * minValueNode(struct Node* node) { struct Node* current = node; /* loop down to find the leftmost leaf */ while (current->left != NULL) current = current->left; return current; } // Recursive function to delete a node with given key // from subtree with given root. It returns root of // the modified subtree. struct Node* deleteNode(struct Node* root, int key) { // STEP 1: PERFORM STANDARD BST DELETE if (root == NULL) return root; // If the key to be deleted is smaller than the // root's key, then it lies in left subtree if ( key < root->key ) root->left = deleteNode(root->left, key); // If the key to be deleted is greater than the // root's key, then it lies in right subtree else if( key > root->key ) root->right = deleteNode(root->right, key); // if key is same as root's key, then This is // the node to be deleted else { // node with only one child or no child if( (root->left == NULL) || (root->right == NULL) ) { struct Node *temp = root->left ? root->left : root->right; // No child case if (temp == NULL) { temp = root; root = NULL; } else // One child case *root = *temp; // Copy the contents of // the non-empty child free(temp); } else { // node with two children: Get the inorder // successor (smallest in the right subtree) struct Node* temp = minValueNode(root->right); // Copy the inorder successor's data to this node root->key = temp->key; // Delete the inorder successor root->right = deleteNode(root->right, temp->key); } } // If the tree had only one node then return if (root == NULL) return root; // STEP 2: UPDATE HEIGHT OF THE CURRENT NODE root->height = 1 + max(height(root->left), height(root->right)); // STEP 3: GET THE BALANCE FACTOR OF THIS NODE (to // check whether this node became unbalanced) int balance = getBalance(root); // If this node becomes unbalanced, then there are 4 cases // Left Left Case if (balance > 1 && getBalance(root->left) >= 0) return rightRotate(root); // Left Right Case if (balance > 1 && getBalance(root->left) < 0) { root->left = leftRotate(root->left); return rightRotate(root); } // Right Right Case if (balance < -1 && getBalance(root->right) <= 0) return leftRotate(root); // Right Left Case if (balance < -1 && getBalance(root->right) > 0) { root->right = rightRotate(root->right); return leftRotate(root); } return root; }