Insert and delete of AVL tree

Source: Internet
Author: User

The AVL tree is a highly balanced two-fork search tree, with the height of the left and right trees of each node not greater than 1. This nature makes the search efficiency of the AVL tree higher than the average two-fork search tree, because for a set of incrementing arrays, the two-fork search tree is a linked list, the search time complexity is naturally o (n), and its composition of the AVL tree is certainly a search efficiency of O (LG (n)) two fork tree. Because of this, in order to maintain the nature of its balance, the insertion and deletion of AVL tree is more complex than the ordinary binary search tree.

1. Maintain the balance of the AVL tree by rotating

The rotation is divided into left and right, and the two operations are symmetrical, as shown in.

After inserting or deleting a node, the AVL tree is rotated in a way that maintains its balance. For a tree with a left subtree taller than the right subtree of 1, if a node is inserted in its left subtree, it will cause the tree to be unbalanced. At this point, the tree can be balanced with one or two rotations.


When the node is inserted under the left subtree of the B-node, it is only necessary to have a right-hand rotation on tree A, as shown in the rotation of tree a Saozi the right subtree will be balanced.

When the node is inserted under the right subtree of the B-node, it is necessary to first turn the left rotation of tree B into the previous case, and then the tree a right-click, as shown in.

After the left-hand rotation of tree B, tree B's Supi right subtree is 1 higher, which translates to the previous case (inserting the node into the left subtree of tree B), and then to the tree a once right to adjust the tree back to the equilibrium state. Why do you want to do a left-hand spin on tree B? Suppose we force Tree B left, directly to tree a right, and get the tree will be as shown.

The rotated tree does not become balanced! The reason is very simple, because when the right-hand tree A, the right subtree of tree B is transferred to tree A, which leads to the tree imbalance before and after the height of this tree is not changed, the tree is still unbalanced, so we need to first by the tree B to the tree B into a Supi right subtree high tree.

The right subtree of Node A is taller than the left subtree, and the node is inserted into the right subtree of Node A, which is completely symmetrical to the above situation.

Below is the code for the left and right of the AVL tree.

void Avlleftrotate (Tree *tree, Node *x) {leftrotate (tree, x); x->height = max (GetHeight (X->left), GetHeight (x-> right) + 1;x->parent->height = x->height + 1;if (x->parent->parent! = NULL) {x->parent->parent- >height = Max (GetHeight (X->parent->parent->left), GetHeight (x->parent->parent->right)) + 1;}} void Avlrightrotate (Tree *tree, Node *x) {rightrotate (tree, x); x->height = max (GetHeight (X->left), GetHeight (x >right) + 1;x->parent->height = x->height + 1;if (x->parent->parent! = NULL) {x->parent-> Parent->height = Max (GetHeight (X->parent->parent->left), GetHeight (X->parent->parent->right) ) + 1;}} void Leftrotate (Tree *tree, node *x) {Node *y = X->right;x->right = Y->left;if (y->left! = Tree->nil &&A mp Y->left = NULL) {y->left->parent = x;} Y->parent = x->parent;if (x->parent = = Tree->nil | | x->parent = NULL) {tree->root = y;} else if (x = = X->pareNt->left) {x->parent->left = y;} Else{x->parent->right = y;}  Y->left = X;x->parent = Y;y->size = x->size;x->size-= ((y->right! = Tree->nil && y->right ! = NULL)? y->right->size:0) + 1;} void Rightrotate (Tree *tree, node *x) {Node *y = X->left;x->left = Y->right;if (y->right! = Tree->nil && Amp Y->right = NULL) {y->right->parent = x;} Y->parent = x->parent;if (x->parent = = Tree->nil | | x->parent = NULL) {tree->root = y;} else if (x = = x->parent->left) {x->parent->left = y;} Else{x->parent->right = y;} Y->right = X;x->parent = Y;y->size = x->size;x->size-= ((Y->left! = Tree->nil && y->left ! = NULL)? y->left->size:0) + 1;}

In the code above, the node's Size property records how many nodes are in the subtree of the node, and the Height property is the tree height of the node.

2. Inserting a new node

The AVL tree after inserting the node may be unbalanced, and we need to rotate to keep the tree balanced. The workflow of the program is:

1). As with the normal two-fork search tree, insert the new node z into the appropriate position as the leaf node;

2). From node Z, go back up, if the parent node of Z zpp is not empty, then judge whether the ZPP is balanced, that is, if the high difference of Saozi right subtree of ZPP is not greater than 1, if the balance is from the parent node of Node Z ZP continue to backtrack, otherwise the balance of ZPP is adjusted by rotation;

3). To rotate the ZPP method is to add the zpp of the left Sub-tree Zl than the right sub-tree ZR High 2, and the Supi right sub-tree of ZL is high, you only need to zpp a right turn, if Zl Supi right sub-tree low, you have to ZL first left-handed, then zpp right-handed. ZPP of the Supi right subtree is 2 lower than the case of symmetric processing can be.

The method to get the tree height of a node is as follows.

int getheight (node *node) {if (node = = NULL) Return-1;return node->height;}

The method for inserting a new node is the same as for a normal two-fork search tree to insert nodes, as shown in the code below.

void Insertavltree (Tree *tree, int value) {Node *node = Createavlnode (value); if (tree->root = = NULL) {tree->root = nod E;return;} Node *n = tree->root;while (1) {n->size++;if (value < N->value) {if (N->left = = NULL) {n->left = node;node- >parent = N;break;} n = n->left;} Else{if (N->right = = NULL) {n->right = Node;node->parent = N;break;} n = n->right;}} Avlinsertfixup (tree, node);}

The key to the above code is that after the insertion node is complete, the newly inserted node node begins to retrace the balance of the tree upward. The code for the Avlinsertfixup method is as follows.

Update the tree height from the inserted new node and maintain the balance through the rotation node void Avlinsertfixup (Tree *tree, node *z) {Node *tmp = Z;while (z! = NULL) {z->height = max (g Etheight (Z->left), GetHeight (z->right)) + 1;if (z->parent! = NULL && z->parent->parent! = null) { Node *ZP = z->parent; Node *zpp = Zp->parent;zp->height = Max (GetHeight (Zp->left), GetHeight (zp->right)) + 1;zpp->height = max ( GetHeight (Zpp->left), GetHeight (zpp->right)) + 1;if (getheight (zpp->left)-getheight (zpp->right) = =-2) {/ /L ZPP Ensure that the right tree of ZP is taller than the left tree high if (getheight (zp->left) > GetHeight (zp->right)) {avlrightrotate (tree, ZP);} Avlleftrotate (tree, ZPP);} else if (getheight (zpp->left)-getheight (zpp->right) = = 2) {//right-turn zpp before making sure that the left tree of ZP is taller than the right tree high if (GetHeight (zp->left) & Lt GetHeight (Zp->right)) {avlleftrotate (tree, ZP);} Avlrightrotate (tree, ZPP);}} z = z->parent;}}

The above code, while backtracking upward, adjusts the tree balance on demand while updating the height of each node.

3. Delete Nodes

Deleting a node can cause the tree's height to change, causing the tree to become unbalanced. The AVL tree Delete node executes the same process as the normal binary search tree, and then from the very beginning, the tree height changes from the node to the first because the node is deleted. The key to this operation is how to determine "the first node that has a high change in the tree". Because there are 3 kinds of deletion nodes in the common binary search tree, there are 3 scenarios for the AVL tree to determine the " first node with high tree height change ". Suppose that the node being deleted is x.

1). x is the leaf node, "The first occurrence of the tree high-change node" is the parent node of X;

2). x there is only one child, "the first occurrence of a tree high-change node" is the parent node of X;

3). x has two children, then "The first occurrence of a tree high-change node" is the parent node of the posterior drive of X.

After determining the "first occurrence of a tree-high change" , it is necessary to backtrack from the node, and, as with the insertion node, rotate the nodes along the road as needed.

The code to delete the node and adjust it after deleting the node is as follows. The following code uses a transplant method to delete a node from the migration tree. After deleting the node like the normal binary search tree, execute the Avldeletefixup method to adjust the tree height to achieve a balanced tree.

/*** replace *tree1 with Tree2, if *tree1 is the root, change the *tree1 directly to */void transplant (Tree *tree, Node *tree1, node *tree2) {if (tree1-> Parent = = NULL) {tree->root = Tree2;tree2->parent = Null;return;} if (tree2! = NULL) tree2->parent = tree1->parent;if (tree1 = = tree1->parent->left) tree1->parent->left = Tree2;elsetree1->parent->right = Tree2;} void Deletefromavltree (Tree *tree, node *node) {if (node = = NULL) return; Node *d = node->parent; Node *n = Node;while (n->parent! = NULL) {n = n->parent;n->size--;} if (Node->left = = NULL) {Transplant (tree, node, node->right);} else if (node->right = = NULL) {Transplant (tree, node, node->left);} Else{tree T;t.root = node->right; Node *min = minimum (&t); Node *end = min->right;min->size = node->size-1;if (node = = tree->root) Tree->root = min;if (node->righ T! = min) {Transplant (tree, Min, min->right); min->right = Node->right;node->right->parent = Min;d = min-& Gt;parent;} else{d = min;} Min->left = Node->left;node->left->parent = Min;transplant (Tree, node, min); n = min->right;while (n! = end) {n-> Size--;n = N->left;}} Avldeletefixup (tree, D); free (node);} From the parent node of the actual deleted node (since the height of the tree is likely to change from that node), adjust the tree height and maintain the balance by rotation void Avldeletefixup (Tree *tree, Node *z) {while (Z! = NULL) {z-> Height = max (getheight (Z->left), GetHeight (z->right)) + 1;if (getheight (z->left)-getheight (z->right) = =-2 {Node *ZR = z->right;if (getheight (Zr->left) > GetHeight (zr->right)) {avlrightrotate (tree, ZR);} Avlleftrotate (tree, z);} else if (getheight (z->left)-getheight (z->right) = = 2) {Node *zl = z->left;if (GetHeight (zl->left) < GetHei Ght (Zl->right)) {Avlleftrotate (tree, ZL);} Avlrightrotate (tree, z);} z = z->parent;}}

4. Time complexity of AVL tree operations

The insertion operation requires O (LG (n)) traversal time and a constant time of up to two rotations;

The delete operation requires O (LG (n)) traversal time and a number of times the constant time of rotation;

In general, the insertion and deletion of AVL trees requires only O (LG (n)) time, but their constant coefficients are different.

Insert and delete of AVL tree

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.