Related Articles

# Insertion, Searching and Deletion in AVL trees containing a parent node pointer

• Last Updated : 14 Jul, 2021

AVL tree is a self-balancing Binary Search Tree (BST) where the difference between heights of left and right subtrees cannot be more than one for all nodes. The insertion and deletion in AVL trees have been discussed in the previous article. In this article, insert, search and delete operations are discussed on AVL trees that also have a parent pointer in their structure.

Definition of AVL tree node:

## C++

 `struct` `AVLwithparent {`` ` `    ``// Pointer to the left and the``    ``// right subtree``    ``struct` `AVLwithparent* left;``    ``struct` `AVLwithparent* right;`` ` `    ``// Stores the data in the node``    ``int` `key;`` ` `    ``// Stores the parent pointer``    ``struct` `AVLwithparent* par;`` ` `    ``// Stores the height of the``    ``// current tree``    ``int` `height;``}`
Output:
```Node: 30, Parent Node: NULL
Node: 20, Parent Node: 30
Node: 10, Parent Node: 20
Node: 25, Parent Node: 20
Node: 40, Parent Node: 30
Node: 50, Parent Node: 40
```

Representation of the Node: Below is the example of an AVL tree containing a parent pointer: Insert Operation: The insertion procedure is similar to that of a normal AVL tree without a parent pointer, but in this case, the parent pointers need to be updated with every insertion and rotation accordingly. Follow the steps below to perform insert operation:

• Perform standard BST insert for the node to be placed at its correct position.
• Increase the height of each node encountered by 1 while finding the correct position for the node to be inserted.
• Update the parent and child pointers of the inserted node and its parent respectively.
• Starting from the inserted node till the root node check if the AVL condition is satisfied for each node on this path.
• If w is the node where the AVL condition is not satisfied then we have 4 cases:
• Left Left Case: (If the left subtree of the left child of w has the inserted node)
• Left Right Case: (If the right subtree of the left child of w has the inserted node)
• Right Left Case: (If the left subtree of the right child of w has the inserted node)
• Right Right Case: (If the right subtree of the right child of w has the inserted node)

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;`` ` `// AVL tree node``struct` `AVLwithparent {``    ``struct` `AVLwithparent* left;``    ``struct` `AVLwithparent* right;``    ``int` `key;``    ``struct` `AVLwithparent* par;``    ``int` `height;``};`` ` `// Function to update the height of``// a node according to its children's``// node's heights``void` `Updateheight(``    ``struct` `AVLwithparent* root)``{``    ``if` `(root != NULL) {`` ` `        ``// Store the height of the``        ``// current node``        ``int` `val = 1;`` ` `        ``// Store the height of the left``        ``// and right substree``        ``if` `(root->left != NULL)``            ``val = root->left->height + 1;`` ` `        ``if` `(root->right != NULL)``            ``val = max(``                ``val, root->right->height + 1);`` ` `        ``// Update the height of the``        ``// current node``        ``root->height = val;``    ``}``}`` ` `// Function to handle Left Left Case``struct` `AVLwithparent* LLR(``    ``struct` `AVLwithparent* root)``{``    ``// Create a reference to the``    ``// left child``    ``struct` `AVLwithparent* tmpnode = root->left;`` ` `    ``// Update the left child of the``    ``// root to the right child of the``    ``// current left child of the root``    ``root->left = tmpnode->right;`` ` `    ``// Update parent pointer of the``    ``// left child of the root node``    ``if` `(tmpnode->right != NULL)``        ``tmpnode->right->par = root;`` ` `    ``// Update the right child of``    ``// tmpnode to root``    ``tmpnode->right = root;`` ` `    ``// Update parent pointer of``    ``// the tmpnode``    ``tmpnode->par = root->par;`` ` `    ``// Update the parent pointer``    ``// of the root``    ``root->par = tmpnode;`` ` `    ``// Update tmpnode as the left or the``    ``// right child of its parent pointer``    ``// according to its key value``    ``if` `(tmpnode->par != NULL``        ``&& root->key < tmpnode->par->key) {``        ``tmpnode->par->left = tmpnode;``    ``}``    ``else` `{``        ``if` `(tmpnode->par != NULL)``            ``tmpnode->par->right = tmpnode;``    ``}`` ` `    ``// Make tmpnode as the new root``    ``root = tmpnode;`` ` `    ``// Update the heights``    ``Updateheight(root->left);``    ``Updateheight(root->right);``    ``Updateheight(root);``    ``Updateheight(root->par);`` ` `    ``// Return the root node``    ``return` `root;``}`` ` `// Function to handle Right Right Case``struct` `AVLwithparent* RRR(``    ``struct` `AVLwithparent* root)``{``    ``// Create a reference to the``    ``// right child``    ``struct` `AVLwithparent* tmpnode = root->right;`` ` `    ``// Update the right child of the``    ``// root as the left child of the``    ``// current right child of the root``    ``root->right = tmpnode->left;`` ` `    ``// Update parent pointer of the``    ``// right child of the root node``    ``if` `(tmpnode->left != NULL)``        ``tmpnode->left->par = root;`` ` `    ``// Update the left child of the``    ``// tmpnode to root``    ``tmpnode->left = root;`` ` `    ``// Update parent pointer of``    ``// the tmpnode``    ``tmpnode->par = root->par;`` ` `    ``// Update the parent pointer``    ``// of the root``    ``root->par = tmpnode;`` ` `    ``// Update tmpnode as the left or``    ``// the right child of its parent``    ``// pointer according to its key value``    ``if` `(tmpnode->par != NULL``        ``&& root->key < tmpnode->par->key) {``        ``tmpnode->par->left = tmpnode;``    ``}``    ``else` `{``        ``if` `(tmpnode->par != NULL)``            ``tmpnode->par->right = tmpnode;``    ``}`` ` `    ``// Make tmpnode as the new root``    ``root = tmpnode;`` ` `    ``// Update the heights``    ``Updateheight(root->left);``    ``Updateheight(root->right);``    ``Updateheight(root);``    ``Updateheight(root->par);`` ` `    ``// Return the root node``    ``return` `root;``}`` ` `// Function to handle Left Right Case``struct` `AVLwithparent* LRR(``    ``struct` `AVLwithparent* root)``{``    ``root->left = RRR(root->left);``    ``return` `LLR(root);``}`` ` `// Function to handle right left case``struct` `AVLwithparent* RLR(``    ``struct` `AVLwithparent* root)``{``    ``root->right = LLR(root->right);``    ``return` `RRR(root);``}`` ` `// Function to insert a node in``// the AVL tree``struct` `AVLwithparent* Insert(``    ``struct` `AVLwithparent* root,``    ``struct` `AVLwithparent* parent,``    ``int` `key)``{`` ` `    ``if` `(root == NULL) {`` ` `        ``// Create and assign values``        ``// to a new node``        ``root = ``new` `struct` `AVLwithparent;`` ` `        ``// If the root is NULL``        ``if` `(root == NULL) {``            ``cout << ``"Error in memory"``                 ``<< endl;``        ``}`` ` `        ``// Otherwise``        ``else` `{``            ``root->height = 1;``            ``root->left = NULL;``            ``root->right = NULL;``            ``root->par = parent;``            ``root->key = key;``        ``}``    ``}`` ` `    ``else` `if` `(root->key > key) {`` ` `        ``// Recur to the left subtree``        ``// to insert the node``        ``root->left = Insert(root->left,``                            ``root, key);`` ` `        ``// Store the heights of the``        ``// left and right subtree``        ``int` `firstheight = 0;``        ``int` `secondheight = 0;`` ` `        ``if` `(root->left != NULL)``            ``firstheight = root->left->height;`` ` `        ``if` `(root->right != NULL)``            ``secondheight = root->right->height;`` ` `        ``// Balance the tree if the``        ``// current node is not balanced``        ``if` `(``abs``(firstheight``                ``- secondheight)``            ``== 2) {`` ` `            ``if` `(root->left != NULL``                ``&& key < root->left->key) {`` ` `                ``// Left Left Case``                ``root = LLR(root);``            ``}``            ``else` `{`` ` `                ``// Left Right Case``                ``root = LRR(root);``            ``}``        ``}``    ``}`` ` `    ``else` `if` `(root->key < key) {`` ` `        ``// Recur to the right subtree``        ``// to insert the node``        ``root->right = Insert(root->right,``                             ``root, key);`` ` `        ``// Store the heights of the``        ``// left and right subtree``        ``int` `firstheight = 0;``        ``int` `secondheight = 0;`` ` `        ``if` `(root->left != NULL)``            ``firstheight``                ``= root->left->height;`` ` `        ``if` `(root->right != NULL)``            ``secondheight = root->right->height;`` ` `        ``// Balance the tree if the``        ``// current node is not balanced``        ``if` `(``abs``(firstheight - secondheight) == 2) {``            ``if` `(root->right != NULL``                ``&& key < root->right->key) {`` ` `                ``// Right Left Case``                ``root = RLR(root);``            ``}``            ``else` `{`` ` `                ``// Right Right Case``                ``root = RRR(root);``            ``}``        ``}``    ``}`` ` `    ``// Case when given key is already``    ``// in the tree``    ``else` `{``    ``}`` ` `    ``// Update the height of the``    ``// root node``    ``Updateheight(root);`` ` `    ``// Return the root node``    ``return` `root;``}`` ` `// Function to print the preorder``// traversal of the AVL tree``void` `printpreorder(``    ``struct` `AVLwithparent* root)``{``    ``// Print the node's value along``    ``// with its parent value``    ``cout << ``"Node: "` `<< root->key``         ``<< ``", Parent Node: "``;`` ` `    ``if` `(root->par != NULL)``        ``cout << root->par->key << endl;``    ``else``        ``cout << ``"NULL"` `<< endl;`` ` `    ``// Recur to the left subtree``    ``if` `(root->left != NULL) {``        ``printpreorder(root->left);``    ``}`` ` `    ``// Recur to the right subtree``    ``if` `(root->right != NULL) {``        ``printpreorder(root->right);``    ``}``}`` ` `// Driver Code``int` `main()``{``    ``struct` `AVLwithparent* root;``    ``root = NULL;`` ` `    ``// Function Call to insert nodes``    ``root = Insert(root, NULL, 10);``    ``root = Insert(root, NULL, 20);``    ``root = Insert(root, NULL, 30);``    ``root = Insert(root, NULL, 40);``    ``root = Insert(root, NULL, 50);``    ``root = Insert(root, NULL, 25);`` ` `    ``// Function call to print the tree``    ``printpreorder(root);``}`
Output:
```Node: 30, Parent Node: NULL
Node: 20, Parent Node: 30
Node: 10, Parent Node: 20
Node: 25, Parent Node: 20
Node: 40, Parent Node: 30
Node: 50, Parent Node: 40
```

Time Complexity: O(log N), where N is the number of nodes of the tree.
Auxiliary Space: O(1)

Search Operation: The search operation in an AVL tree with parent pointers is similar to the search operation in a normal Binary Search Tree. Follow the steps below to perform search operation:

• Start from the root node.
• If the root node is NULL, return false.
• Check if the current node’s value is equal to the value of the node to be searched. If yes, return true.
• If the current node’s value is less than searched key then recur to the right subtree.
• If the current node’s value is greater than searched key then recur to the left subtree.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;`` ` `// AVL tree node``struct` `AVLwithparent {``    ``struct` `AVLwithparent* left;``    ``struct` `AVLwithparent* right;``    ``int` `key;``    ``struct` `AVLwithparent* par;``    ``int` `height;``};`` ` `// Function to update the height of``// a node according to its children's``// node's heights``void` `Updateheight(``struct` `AVLwithparent* root)``{``    ``if` `(root != NULL) {`` ` `        ``// Store the height of the``        ``// current node``        ``int` `val = 1;`` ` `        ``// Store the height of the left``        ``// and the right substree``        ``if` `(root->left != NULL)``            ``val = root->left->height + 1;`` ` `        ``if` `(root->right != NULL)``            ``val = max(``                ``val, root->right->height + 1);`` ` `        ``// Update the height of the``        ``// current node``        ``root->height = val;``    ``}``}`` ` `// Function to handle Left Left Case``struct` `AVLwithparent* LLR(``    ``struct` `AVLwithparent* root)``{``    ``// Create a reference to the``    ``// left child``    ``struct` `AVLwithparent* tmpnode = root->left;`` ` `    ``// Update the left child of the``    ``// root to the right child of the``    ``// current left child of the root``    ``root->left = tmpnode->right;`` ` `    ``// Update parent pointer of the left``    ``// child of the root node``    ``if` `(tmpnode->right != NULL)``        ``tmpnode->right->par = root;`` ` `    ``// Update the right child of``    ``// tmpnode to root``    ``tmpnode->right = root;`` ` `    ``// Update parent pointer of tmpnode``    ``tmpnode->par = root->par;`` ` `    ``// Update the parent pointer of root``    ``root->par = tmpnode;`` ` `    ``// Update tmpnode as the left or``    ``// the right child of its parent``    ``// pointer according to its key value``    ``if` `(tmpnode->par != NULL``        ``&& root->key < tmpnode->par->key) {``        ``tmpnode->par->left = tmpnode;``    ``}``    ``else` `{``        ``if` `(tmpnode->par != NULL)``            ``tmpnode->par->right = tmpnode;``    ``}`` ` `    ``// Make tmpnode as the new root``    ``root = tmpnode;`` ` `    ``// Update the heights``    ``Updateheight(root->left);``    ``Updateheight(root->right);``    ``Updateheight(root);``    ``Updateheight(root->par);`` ` `    ``// Return the root node``    ``return` `root;``}`` ` `// Function to handle Right Right Case``struct` `AVLwithparent* RRR(``    ``struct` `AVLwithparent* root)``{``    ``// Create a reference to the``    ``// right child``    ``struct` `AVLwithparent* tmpnode = root->right;`` ` `    ``// Update the right child of the``    ``// root as the left child of the``    ``// current right child of the root``    ``root->right = tmpnode->left;`` ` `    ``// Update parent pointer of the right``    ``// child of the root node``    ``if` `(tmpnode->left != NULL)``        ``tmpnode->left->par = root;`` ` `    ``// Update the left child of the``    ``// tmpnode to root``    ``tmpnode->left = root;`` ` `    ``// Update parent pointer of tmpnode``    ``tmpnode->par = root->par;`` ` `    ``// Update the parent pointer of root``    ``root->par = tmpnode;`` ` `    ``// Update tmpnode as the left or``    ``// the right child of its parent``    ``// pointer according to its key value``    ``if` `(tmpnode->par != NULL``        ``&& root->key < tmpnode->par->key) {``        ``tmpnode->par->left = tmpnode;``    ``}``    ``else` `{``        ``if` `(tmpnode->par != NULL)``            ``tmpnode->par->right = tmpnode;``    ``}`` ` `    ``// Make tmpnode as the new root``    ``root = tmpnode;`` ` `    ``// Update the heights``    ``Updateheight(root->left);``    ``Updateheight(root->right);``    ``Updateheight(root);``    ``Updateheight(root->par);`` ` `    ``// Return the root node``    ``return` `root;``}`` ` `// Function to handle Left Right Case``struct` `AVLwithparent* LRR(``    ``struct` `AVLwithparent* root)``{``    ``root->left = RRR(root->left);``    ``return` `LLR(root);``}`` ` `// Function to handle right left case``struct` `AVLwithparent* RLR(``    ``struct` `AVLwithparent* root)``{``    ``root->right = LLR(root->right);``    ``return` `RRR(root);``}`` ` `// Function to insert a node in``// the AVL tree``struct` `AVLwithparent* Insert(``    ``struct` `AVLwithparent* root,``    ``struct` `AVLwithparent* parent,``    ``int` `key)``{`` ` `    ``if` `(root == NULL) {`` ` `        ``// Create and assign values``        ``// to a new node``        ``root = ``new` `struct` `AVLwithparent;``        ``if` `(root == NULL) {``            ``cout << ``"Error in memory"` `<< endl;``        ``}`` ` `        ``// Otherwise``        ``else` `{``            ``root->height = 1;``            ``root->left = NULL;``            ``root->right = NULL;``            ``root->par = parent;``            ``root->key = key;``        ``}``    ``}`` ` `    ``else` `if` `(root->key > key) {`` ` `        ``// Recur to the left subtree``        ``// to insert the node``        ``root->left = Insert(root->left,``                            ``root, key);`` ` `        ``// Stores the heights of the``        ``// left and right subtree``        ``int` `firstheight = 0;``        ``int` `secondheight = 0;`` ` `        ``if` `(root->left != NULL)``            ``firstheight = root->left->height;`` ` `        ``if` `(root->right != NULL)``            ``secondheight = root->right->height;`` ` `        ``// Balance the tree if the``        ``// current node is not balanced``        ``if` `(``abs``(firstheight``                ``- secondheight)``            ``== 2) {`` ` `            ``if` `(root->left != NULL``                ``&& key < root->left->key) {`` ` `                ``// Left Left Case``                ``root = LLR(root);``            ``}``            ``else` `{`` ` `                ``// Left Right Case``                ``root = LRR(root);``            ``}``        ``}``    ``}`` ` `    ``else` `if` `(root->key < key) {`` ` `        ``// Recur to the right subtree``        ``// to insert the node``        ``root->right = Insert(root->right, root, key);`` ` `        ``// Store the heights of the left``        ``// and right subtree``        ``int` `firstheight = 0;``        ``int` `secondheight = 0;`` ` `        ``if` `(root->left != NULL)``            ``firstheight = root->left->height;`` ` `        ``if` `(root->right != NULL)``            ``secondheight = root->right->height;`` ` `        ``// Balance the tree if the``        ``// current node is not balanced``        ``if` `(``abs``(firstheight``                ``- secondheight)``            ``== 2) {``            ``if` `(root->right != NULL``                ``&& key < root->right->key) {`` ` `                ``// Right Left Case``                ``root = RLR(root);``            ``}``            ``else` `{`` ` `                ``// Right Right Case``                ``root = RRR(root);``            ``}``        ``}``    ``}`` ` `    ``// Case when given key is``    ``// already in tree``    ``else` `{``    ``}`` ` `    ``// Update the height of the``    ``// root node``    ``Updateheight(root);`` ` `    ``// Return the root node``    ``return` `root;``}`` ` `// Function to find a key in AVL tree``bool` `AVLsearch(``    ``struct` `AVLwithparent* root, ``int` `key)``{``    ``// If root is NULL``    ``if` `(root == NULL)``        ``return` `false``;`` ` `    ``// If found, return true``    ``else` `if` `(root->key == key)``        ``return` `true``;`` ` `    ``// Recur to the left subtree if``    ``// the current node's value is``    ``// greater than key``    ``else` `if` `(root->key > key) {``        ``bool` `val = AVLsearch(root->left, key);``        ``return` `val;``    ``}`` ` `    ``// Otherwise, recur to the``    ``// right subtree``    ``else` `{``        ``bool` `val = AVLsearch(root->right, key);``        ``return` `val;``    ``}``}`` ` `// Driver Code``int` `main()``{``    ``struct` `AVLwithparent* root;``    ``root = NULL;`` ` `    ``// Function call to insert the nodes``    ``root = Insert(root, NULL, 10);``    ``root = Insert(root, NULL, 20);``    ``root = Insert(root, NULL, 30);``    ``root = Insert(root, NULL, 40);``    ``root = Insert(root, NULL, 50);``    ``root = Insert(root, NULL, 25);`` ` `    ``// Function call to search for a node``    ``bool` `found = AVLsearch(root, 40);``    ``if` `(found)``        ``cout << ``"value found"``;``    ``else``        ``cout << ``"value not found"``;`` ` `    ``return` `0;``}`
Output:
```value found
```

Time Complexity: O(log N), where N is the number of nodes of the tree
Auxiliary Space: O(1)

Delete Operation: The deletion procedure is similar to that of a normal AVL tree without a parent pointer, but in this case, the references to the parent pointers need to be updated with every deletion and rotation accordingly. Follow the steps below to perform the delete operation:

• Perform the delete procedure as in a normal BST.
• From the node that has been deleted, move towards the root.
• At each node on the path, update the height of the node.
• Check for AVL conditions at each node. Let there be 3 nodes: w, x, y where w is the current node, x is the root of the subtree of w which has greater height and y is the root of the subtree of x which has greater height.
• If the node w is unbalanced, there exists one of the following 4 cases:
• Left Left Case (x is left child of w and y is left child of x)
• Left Right Case (x is left child of w and y is right child of x)
• Right Left Case (x is right child of w and y is left child of x)
• Right Right Case (x is right child of w and y is right child of x)

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;`` ` `// AVL tree node``struct` `AVLwithparent {``    ``struct` `AVLwithparent* left;``    ``struct` `AVLwithparent* right;``    ``int` `key;``    ``struct` `AVLwithparent* par;``    ``int` `height;``};`` ` `// Function to print the preorder``// traversal of the AVL tree``void` `printpreorder(``struct` `AVLwithparent* root)``{``    ``// Print the node's value along``    ``// with its parent value``    ``cout << ``"Node: "` `<< root->key``         ``<< ``", Parent Node: "``;`` ` `    ``if` `(root->par != NULL)``        ``cout << root->par->key << endl;``    ``else``        ``cout << ``"NULL"` `<< endl;`` ` `    ``// Recur to the left subtree``    ``if` `(root->left != NULL) {``        ``printpreorder(root->left);``    ``}`` ` `    ``// Recur to the right subtree``    ``if` `(root->right != NULL) {``        ``printpreorder(root->right);``    ``}``}`` ` `// Function to update the height of``// a node according to its children's``// node's heights``void` `Updateheight(``    ``struct` `AVLwithparent* root)``{``    ``if` `(root != NULL) {`` ` `        ``// Store the height of the``        ``// current node``        ``int` `val = 1;`` ` `        ``// Store the height of the left``        ``// and right substree``        ``if` `(root->left != NULL)``            ``val = root->left->height + 1;`` ` `        ``if` `(root->right != NULL)``            ``val = max(``                ``val, root->right->height + 1);`` ` `        ``// Update the height of the``        ``// current node``        ``root->height = val;``    ``}``}`` ` `// Function to handle Left Left Case``struct` `AVLwithparent* LLR(``    ``struct` `AVLwithparent* root)``{``    ``// Create a reference to the``    ``// left child``    ``struct` `AVLwithparent* tmpnode = root->left;`` ` `    ``// Update the left child of the``    ``// root to the right child of the``    ``// current left child of the root``    ``root->left = tmpnode->right;`` ` `    ``// Update parent pointer of left``    ``// child of the root node``    ``if` `(tmpnode->right != NULL)``        ``tmpnode->right->par = root;`` ` `    ``// Update the right child of``    ``// tmpnode to root``    ``tmpnode->right = root;`` ` `    ``// Update parent pointer of tmpnode``    ``tmpnode->par = root->par;`` ` `    ``// Update the parent pointer of root``    ``root->par = tmpnode;`` ` `    ``// Update tmpnode as the left or``    ``// the right child of its parent``    ``// pointer according to its key value``    ``if` `(tmpnode->par != NULL``        ``&& root->key < tmpnode->par->key) {``        ``tmpnode->par->left = tmpnode;``    ``}``    ``else` `{``        ``if` `(tmpnode->par != NULL)``            ``tmpnode->par->right = tmpnode;``    ``}`` ` `    ``// Make tmpnode as the new root``    ``root = tmpnode;`` ` `    ``// Update the heights``    ``Updateheight(root->left);``    ``Updateheight(root->right);``    ``Updateheight(root);``    ``Updateheight(root->par);`` ` `    ``// Return the root node``    ``return` `root;``}`` ` `// Function to handle Right Right Case``struct` `AVLwithparent* RRR(``    ``struct` `AVLwithparent* root)``{``    ``// Create a reference to the``    ``// right child``    ``struct` `AVLwithparent* tmpnode = root->right;`` ` `    ``// Update the right child of the``    ``// root as the left child of the``    ``// current right child of the root``    ``root->right = tmpnode->left;`` ` `    ``// Update parent pointer of the``    ``// right child of the root node``    ``if` `(tmpnode->left != NULL)``        ``tmpnode->left->par = root;`` ` `    ``// Update the left child of the``    ``// tmpnode to root``    ``tmpnode->left = root;`` ` `    ``// Update parent pointer of tmpnode``    ``tmpnode->par = root->par;`` ` `    ``// Update the parent pointer of root``    ``root->par = tmpnode;`` ` `    ``// Update tmpnode as the left or``    ``// the right child of its parent``    ``// pointer according to its key value``    ``if` `(tmpnode->par != NULL``        ``&& root->key < tmpnode->par->key) {``        ``tmpnode->par->left = tmpnode;``    ``}``    ``else` `{``        ``if` `(tmpnode->par != NULL)``            ``tmpnode->par->right = tmpnode;``    ``}`` ` `    ``// Make tmpnode as the new root``    ``root = tmpnode;`` ` `    ``// Update the heights``    ``Updateheight(root->left);``    ``Updateheight(root->right);``    ``Updateheight(root);``    ``Updateheight(root->par);`` ` `    ``// Return the root node``    ``return` `root;``}`` ` `// Function to handle Left Right Case``struct` `AVLwithparent* LRR(``    ``struct` `AVLwithparent* root)``{``    ``root->left = RRR(root->left);``    ``return` `LLR(root);``}`` ` `// Function to handle right left case``struct` `AVLwithparent* RLR(``    ``struct` `AVLwithparent* root)``{``    ``root->right = LLR(root->right);``    ``return` `RRR(root);``}`` ` `// Function to balance the tree after``// deletion of a node``struct` `AVLwithparent* Balance(``    ``struct` `AVLwithparent* root)``{``    ``// Store the current height of``    ``// the left and right subtree``    ``int` `firstheight = 0;``    ``int` `secondheight = 0;`` ` `    ``if` `(root->left != NULL)``        ``firstheight = root->left->height;`` ` `    ``if` `(root->right != NULL)``        ``secondheight = root->right->height;`` ` `    ``// If current node is not balanced``    ``if` `(``abs``(firstheight - secondheight) == 2) {``        ``if` `(firstheight < secondheight) {`` ` `            ``// Store the height of the``            ``// left and right subtree``            ``// of the current node's``            ``// right subtree``            ``int` `rightheight1 = 0;``            ``int` `rightheight2 = 0;``            ``if` `(root->right->right != NULL)``                ``rightheight2 = root->right->right->height;`` ` `            ``if` `(root->right->left != NULL)``                ``rightheight1 = root->right->left->height;`` ` `            ``if` `(rightheight1 > rightheight2) {`` ` `                ``// Right Left Case``                ``root = RLR(root);``            ``}``            ``else` `{`` ` `                ``// Right Right Case``                ``root = RRR(root);``            ``}``        ``}``        ``else` `{`` ` `            ``// Store the height of the``            ``// left and right subtree``            ``// of the current node's``            ``// left subtree``            ``int` `leftheight1 = 0;``            ``int` `leftheight2 = 0;``            ``if` `(root->left->right != NULL)``                ``leftheight2 = root->left->right->height;`` ` `            ``if` `(root->left->left != NULL)``                ``leftheight1 = root->left->left->height;`` ` `            ``if` `(leftheight1 > leftheight2) {`` ` `                ``// Left Left Case``                ``root = LLR(root);``            ``}``            ``else` `{`` ` `                ``// Left Right Case``                ``root = LRR(root);``            ``}``        ``}``    ``}`` ` `    ``// Return the root node``    ``return` `root;``}`` ` `// Function to insert a node in``// the AVL tree``struct` `AVLwithparent* Insert(``    ``struct` `AVLwithparent* root,``    ``struct` `AVLwithparent* parent,``    ``int` `key)``{`` ` `    ``if` `(root == NULL) {`` ` `        ``// Create and assign values``        ``// to a new node``        ``root = ``new` `struct` `AVLwithparent;``        ``if` `(root == NULL)``            ``cout << ``"Error in memory"` `<< endl;``        ``else` `{``            ``root->height = 1;``            ``root->left = NULL;``            ``root->right = NULL;``            ``root->par = parent;``            ``root->key = key;``        ``}``    ``}`` ` `    ``else` `if` `(root->key > key) {`` ` `        ``// Recur to the left subtree``        ``// to insert the node``        ``root->left = Insert(root->left,``                            ``root, key);`` ` `        ``// Store the heights of the``        ``// left and right subtree``        ``int` `firstheight = 0;``        ``int` `secondheight = 0;`` ` `        ``if` `(root->left != NULL)``            ``firstheight = root->left->height;`` ` `        ``if` `(root->right != NULL)``            ``secondheight = root->right->height;`` ` `        ``// Balance the tree if the``        ``// current node is not balanced``        ``if` `(``abs``(firstheight``                ``- secondheight)``            ``== 2) {`` ` `            ``if` `(root->left != NULL``                ``&& key < root->left->key) {`` ` `                ``// Left Left Case``                ``root = LLR(root);``            ``}``            ``else` `{`` ` `                ``// Left Right Case``                ``root = LRR(root);``            ``}``        ``}``    ``}`` ` `    ``else` `if` `(root->key < key) {`` ` `        ``// Recur to the right subtree``        ``// to insert the node``        ``root->right = Insert(root->right,``                             ``root, key);`` ` `        ``// Store the heights of the left``        ``// and right subtree``        ``int` `firstheight = 0;``        ``int` `secondheight = 0;`` ` `        ``if` `(root->left != NULL)``            ``firstheight = root->left->height;`` ` `        ``if` `(root->right != NULL)``            ``secondheight = root->right->height;`` ` `        ``// Balance the tree if the``        ``// current node is not balanced``        ``if` `(``abs``(firstheight - secondheight) == 2) {``            ``if` `(root->right != NULL``                ``&& key < root->right->key) {`` ` `                ``// Right Left Case``                ``root = RLR(root);``            ``}``            ``else` `{`` ` `                ``// Right Right Case``                ``root = RRR(root);``            ``}``        ``}``    ``}`` ` `    ``// Case when given key is``    ``// already in tree``    ``else` `{``    ``}`` ` `    ``// Update the height of the``    ``// root node``    ``Updateheight(root);`` ` `    ``// Return the root node``    ``return` `root;``}`` ` `// Function to delete a node from``// the AVL tree``struct` `AVLwithparent* Delete(``    ``struct` `AVLwithparent* root,``    ``int` `key)``{``    ``if` `(root != NULL) {`` ` `        ``// If the node is found``        ``if` `(root->key == key) {`` ` `            ``// Replace root with its``            ``// left child``            ``if` `(root->right == NULL``                ``&& root->left != NULL) {``                ``if` `(root->par != NULL) {``                    ``if` `(root->par->key``                        ``< root->key)``                        ``root->par->right = root->left;``                    ``else``                        ``root->par->left = root->left;`` ` `                    ``// Update the height``                    ``// of root's parent``                    ``Updateheight(root->par);``                ``}`` ` `                ``root->left->par = root->par;`` ` `                ``// Balance the node``                ``// after deletion``                ``root->left = Balance(``                    ``root->left);`` ` `                ``return` `root->left;``            ``}`` ` `            ``// Replace root with its``            ``// right child``            ``else` `if` `(root->left == NULL``                     ``&& root->right != NULL) {``                ``if` `(root->par != NULL) {``                    ``if` `(root->par->key``                        ``< root->key)``                        ``root->par->right = root->right;``                    ``else``                        ``root->par->left = root->right;`` ` `                    ``// Update the height``                    ``// of the root's parent``                    ``Updateheight(root->par);``                ``}`` ` `                ``root->right->par = root->par;`` ` `                ``// Balance the node after``                ``// deletion``                ``root->right = Balance(root->right);``                ``return` `root->right;``            ``}`` ` `            ``// Remove the references of``            ``// the current node``            ``else` `if` `(root->left == NULL``                     ``&& root->right == NULL) {``                ``if` `(root->par->key < root->key) {``                    ``root->par->right = NULL;``                ``}``                ``else` `{``                    ``root->par->left = NULL;``                ``}`` ` `                ``if` `(root->par != NULL)``                    ``Updateheight(root->par);`` ` `                ``root = NULL;``                ``return` `NULL;``            ``}`` ` `            ``// Otherwise, replace the``            ``// current node with its``            ``// successor and then``            ``// recursively call Delete()``            ``else` `{``                ``struct` `AVLwithparent* tmpnode = root;``                ``tmpnode = tmpnode->right;``                ``while` `(tmpnode->left != NULL) {``                    ``tmpnode = tmpnode->left;``                ``}`` ` `                ``int` `val = tmpnode->key;`` ` `                ``root->right``                    ``= Delete(root->right, tmpnode->key);`` ` `                ``root->key = val;`` ` `                ``// Balance the node``                ``// after deletion``                ``root = Balance(root);``            ``}``        ``}`` ` `        ``// Recur to the right subtree to``        ``// delete the current node``        ``else` `if` `(root->key < key) {``            ``root->right = Delete(root->right, key);`` ` `            ``root = Balance(root);``        ``}`` ` `        ``// Recur into the right subtree``        ``// to delete the current node``        ``else` `if` `(root->key > key) {``            ``root->left = Delete(root->left, key);`` ` `            ``root = Balance(root);``        ``}`` ` `        ``// Update height of the root``        ``if` `(root != NULL) {``            ``Updateheight(root);``        ``}``    ``}`` ` `    ``// Handle the case when the key to be``    ``// deleted could not be found``    ``else` `{``        ``cout << ``"Key to be deleted "``             ``<< ``"could not be found\n"``;``    ``}`` ` `    ``// Return the root node``    ``return` `root;``}`` ` `// Driver Code``int` `main()``{``    ``struct` `AVLwithparent* root;``    ``root = NULL;`` ` `    ``// Function call to insert the nodes``    ``root = Insert(root, NULL, 9);``    ``root = Insert(root, NULL, 5);``    ``root = Insert(root, NULL, 10);``    ``root = Insert(root, NULL, 0);``    ``root = Insert(root, NULL, 6);`` ` `    ``// Print the tree before deleting node``    ``cout << ``"Before deletion:\n"``;``    ``printpreorder(root);`` ` `    ``// Function Call to delete node 10``    ``root = Delete(root, 10);`` ` `    ``// Print the tree after deleting node``    ``cout << ``"After deletion:\n"``;``    ``printpreorder(root);``}`
Output:
```Before deletion:
Node: 9, Parent Node: NULL
Node: 5, Parent Node: 9
Node: 0, Parent Node: 5
Node: 6, Parent Node: 5
Node: 10, Parent Node: 9
After deletion:
Node: 6, Parent Node: NULL
Node: 5, Parent Node: 6
Node: 0, Parent Node: 5
Node: 9, Parent Node: 6
```

Time Complexity: O(log N), where N is the number of nodes of the tree
Auxiliary Space: O(1)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

My Personal Notes arrow_drop_up