AVL Insert, delete operation

Source: Internet
Author: User

The height of the two subtrees of any node in the AVL tree is the maximum difference of one, so it is also called a height-balanced tree. Find, insert, and delete are O (log n) in both the average and worst case scenarios. Additions and deletions may require one or more tree rotations to rebalance the tree.

The AVL tree can be either an empty tree or a tree with the following properties:
(1): All of his left and right subtrees are AVL trees.
(2): Saozi The right subtree height difference (balance factor) of the absolute value of not more than 1

Characteristics:
The AVL tree is essentially a binary search tree, which is characterized by:
1. itself is first a binary search tree.
2. With equilibrium condition: the absolute value (balance factor) of the difference of the height of the left and right sub-tree of each node is up to 1.
In other words, the AVL tree is essentially a two-fork lookup tree with a balanced function (binary sort tree, binary search tree). Operation:

Rotating

The basic operation of the AVL tree generally involves the same algorithm that is carried out in an unbalanced two-fork search tree. But to do one or more of the so-called "AVL rotations" beforehand or later.
Assuming that the pointer to the root node of the least-balanced tree is a (i.e. a is closest to the insertion point and the absolute value of the balance factor exceeds 1 of the ancestor node) due to the insertion of the node on the binary sort trees, then the rule after loss of balance can be summed up in the following four cases:

Unidirectional left-balance processing R: Due to the insertion of nodes on the right subtree of the right subtree node of *a, the balance factor of *a is changed from 1 to 2, resulting in the loss of balance of the subtree with the root of *a, and a left rotation operation is required;

Single right-balance processing L: Due to the insertion of nodes in the left subtree of the Zogen node of *a, the balance factor of *a increases from 1 to 2, resulting in the loss of balance of the subtree with the root of the *a, and a right rotation operation is required;



Bidirectional rotation (first left and right) balanced processing LR: Due to the insertion of nodes in the right subtree of the Zogen node of the *a, the balance factor of *a is increased from 1 to 2, resulting in the loss of balance of the subtree with the root of the *a, two rotations (first left-handed and right-handed) operation.

Bidirectional rotation (first right rear left) balanced processing RL: Due to the insertion of a node in the left subtree of the right subtree node of the *a, the balance factor of the *a is changed from 1 to 2, resulting in the loss of balance of the subtree with the root of the *a, two rotations (first right-hand and back-l) operation

Insert

When inserting a new node into a highly balanced AVL tree, an imbalance occurs if the absolute value of the balance factor for a node in the tree is >1. Set the new insertion node to p, from the node p to the root node of the path, each node is the root of the height of the subtree may increase by 1, so after each execution of the binary search tree insert operation, you need to start from the newly inserted node p, along the node inserted in the path to the root node direction, modify the balance factor of each node, adjust the height of the whole tree degree, restoring the equilibrium nature of being destroyed.

Insert node P (key) node algorithm in the AVL tree:

Step one: If the tree is empty, the root node is inserted and returned directly
Step two: If the tree is not empty, look for the insertion position, if found in the process of finding key, then insert failed to return directly
Step three: Inserting nodes
Step four: Update the balance factor to adjust the tree

The balance factor of the new node P is 0, but the balance factor of its parent node PR is three cases:

1, node PR balance factor of 0 in the PR of the lower sub-tree Insert new node, node PR balance, its height does not increase, at this time from the PR to the root path
The height of the subtree of the root of each node is constant, that is, the equilibrium factor of each node is invariable, and the equilibrium treatment is ended.

2. The absolute value of the balance factor of the node PR is 1    , the balance factor of the pre-insertion PR is 0, the sub-tree with PR as the root is not lost, but the height of the subtree is increased
    , it needs to backtrack from the node pr to the root, and continue to view the balance of the parent node of PR.

3, the node PR balance factor of the absolute value of 2
The new node is inserted at a higher subtree and needs to be treated in a balanced format:
If PR = 2, indicating the right sub-tree height, set the right sub-tree of PR Q
When Q has a balance factor of 1, the left single rotation is performed
When Q balance factor is-1, perform first right after left double rotation
If PR =-2, indicating left dial hand tree height, set PR of the left sub-tree for Q
When Q's balance factor is-1, the right single rotation is performed
When Q balance factor is 1, perform first left and right double rotation
After rotation, PR is the root of the subtree height reduction, no need to continue back to the upper layer

*

Delete:

To remove a node from the AVL tree, you must first detect the existence of that node, and if it is possible to destroy the height balance of the AVL tree after it has been deleted, you need to do a balanced rotation.
The deleted node P has the following conditions:

1. Deleted node P has two children
First, the direct precursor Q (or direct successor) of p in the middle sequence traversal is searched. Then send the contents of the node Q to P, the problem is shifted from the deletion of nodes p to delete node Q, it is only one child node.

2. Deleted node P max only one child q
P's parent node PR to point to P's pointer to point to the Q, if p does not have children, the corresponding pointer of the PR directly to NULL. Then the original PR-rooted subtree of the height minus 1, and along the path of the PR to the root of the reverse tracking height changes on the path of the effect of the various nodes.

Test node Q's parents node p, if q is the left child of PR, then the PR balance factor increased by 1, otherwise reduced by 1, according to the modified PR balance factor value, divided into three kinds of situations processing:

1, the PR balance factor was originally 0, in its left (or right) subtree Delete node, its balance factor increases (decrease) 1,pr height unchanged, so from the PR to the root of all the node height is unchanged, without adjustment.

2, the PR original balance factor is not 0, and the higher the subtree is shortened, PR balance factor becomes 0, the PR is the root of the sub-tree balance, its height minus 1, but need to check the balance of the parent node of PR.

3, the node PR balance factor is not 0, and the dwarf tree is shortened, the PR imbalance, need to balance the rotation order to make it balanced. Make PR higher subtree root is q, according to Q balance factor, divide three kinds of situation
A, if the balance factor of Q is 0, perform a single rotation recovery PR
b, if the balance factor of Q is the same as the PR balance factor (positive or negative), a single rotation recovery PR is performed
c, if Q balance factor and PR balance factor (positive or negative) number opposite, then perform a double rotation recovery PR

Code implementation:

#include <iostream> using namespace std;  
    Template<class k,class v> struct Avltreenode//node structure {typedef avltreenode<k, v> Node;  
    node* _pleft;  
    node* _pright;  

    node* _pparent;  
    K _key;  
    V _value;  
    int _BF;  
        Avltreenode (const k& key,const v& value): _key (Key), _value (value), _pleft (NULL)  

, _pright (null), _pparent (null), _BF (0)//Balance Factor {}};  
Template<class K,class v> class Avltree {typedef avltreenode<k, v> Node;  
        Public:avltree (): _proot (NULL) {} bool Insert (const k& key, const v& value) {  
            Determine if the tree exists if (NULL = = _proot) {_proot = new Node (key, value);  
        return true;  
        }//Find the insertion position node* cur = _proot;  
        node* parent = NULL; while (cur) {if (cur->_key < key) {parent = cur;  
            Cur = cur->_pright;  
                } else if (cur->_key>key) {parent = cur;  
            Cur = cur->_pleft;  
            } else {return false;  }}//Insert new node, parents must be balanced, but parents are not necessarily balanced, if (Parent->_key < key) {node*  
            TMP = new Node (key, value);  
            Parent->_pright = tmp;  
            Tmp->_pparent = parent;  
        parent->_bf++;  
            } if (Parent->_key>key) {node* tmp = new Node (key, value);  
            Parent->_pleft = tmp;  
            Tmp->_pparent = parent;  
        parent->_bf--; }//Update parent's balance factor while (parent) {if (PARENT-&GT;_BF = = 0)//original is 1 or-1, then insert will not be to the height of the tree  
            have an impact;  
          {      return true; } else if (PARENT-&GT;_BF = = 1 | | parent->_bf = =-1)//original is 0, has an effect on the height of the tree {No  
                de* pparent = parent->_pparent;  
                        if (pparent! = NULL) {if (Pparent->_pleft = = parent)//height increase on left tree  
                    pparent->_bf--;  
                else//Right tree height increase pparent->_bf++;  
            } parent = pparent;  
                The else//balance factor is 2/-2, which changes from 1 or 1, does not satisfy the balance tree, requires rotation {if (PARENT-&GT;_BF = = 2)//right tree too high  
                        {if (PARENT-&GT;_PRIGHT-&GT;_BF = = 1)//need left-hand structure {  
                        _rotatel (parent);  
                    return true;  
                        } else if (PARENT-&GT;_PRIGHT-&GT;_BF =-1)//need right Left-hand structure {  
_rotaterl (parent);                        return true; }} else//Balance factor is-2 {if (Parent->_pleft-&gt  
                        ; _BF = =-1)//structure requiring right paddle {_rotater (parent);  
                    return true;  
                        } else if (PARENT-&GT;_PLEFT-&GT;_BF = = 1)//structure requiring left and right rotation {  
                        _ROTATELR (parent);  
                    return true;
        }}}}} bool Remove (const k& key, const v& value) {

        The binary search tree has no node if (_proot = = NULL) return false; The binary search tree has only the root node if (_proot->_pleft = = NULL && _proot->_pright = = null) {if (_proot-
                >_key = = key) {Delete _proot;
                _proot = NULL;
       return true;     } return false;
        } node* pcur = _proot;

        node* parent = NULL; 
            The Traverse finds the location to delete the node while (pcur) {node* Pdel = NULL;
                if (Pcur->_key < key) {parent = Pcur;
            Pcur = pcur->_pright;
                } else if (Pcur->_key > key) {parent = Pcur;
            Pcur = pcur->_pleft;
                } else {//The left subtree of the node to be deleted is empty if (Pcur->_pleft = = null)  
                        {//determines if the parent node is empty, if NULL, the node to be deleted is the root node if (parent = = NULL) {  
                        _proot = pcur->_pright;  
                        Delete pcur;  
                        Pcur = NULL;  
                    return true;
                } else if (Parent->_key < key)//right subtree {        Pdel = Pcur;
                        Parent->_pright = pcur->_pright;
                        Delete Pdel;
                        Pdel = NULL;
                    return true;
                        } else//left dial hand tree {Pdel = pcur;
                        Parent->_pleft = pcur->_pright;
                        Delete Pdel;
                        Pdel = NULL;
                    return true;
                    }}//The right subtree of the node to be deleted is empty else if (pcur->_pright = = NULL) {  
                        Determines whether the parent node is empty, if NULL, the node to be deleted is the root node if (parent = = NULL) {  
                        _proot = pcur->_pleft;  
                        Delete pcur;  
                        Pcur = NULL;  
                    return true;
              } else if (Parent->_key > key)//Zuozi      {Pdel = Pcur;
                        Parent->_pleft = pcur->_pleft;
                        Delete pcur;
                        Pcur = NULL;
                    return true;
                        } else//right subtree {pdel = pcur;
                        Parent->_pright = pcur->_pleft;
                        Delete Pdel;
                        Pdel = NULL;
                    return true;
                }}///The subtree is not a null//right subtree that iterates through the first node, replacing the value of the deleted node with its value, deleting the Else  
                    {node* Pdel = pcur;  
                    node* parent = NULL; 

                    node* Rightfirst = pcur->_pright;  
                        The left sub-tree of the first node on the right is empty if (Rightfirst->_pleft = = null) {  
          Swap (Rightfirst->_key, pcur->_key);              Swap (Rightfirst->_value, pcur->_value);  
                        The value of the Exchange delete node and the middle order traverse the first node, that is, the leftmost node Pdel = Rightfirst;  
                        Pcur->_pright = rightfirst->_pright;  
                        Delete Pdel;  
                    return true;  
                        }//The left subtree of the first node on the right is not empty while (Rightfirst->_pleft) {  
                        parent = Rightfirst;  
                    Rightfirst = rightfirst->_pleft;  
                    } swap (Rightfirst->_key, pcur->_key);  
                    Swap (Rightfirst->_value, pcur->_value);  
                    Pdel = Rightfirst;  
                    Parent->_pleft = rightfirst->_pright;  
                    Delete Pdel;    
                return true; }}}//update balance factor while (parent) {//update balance DueSub if (Parent->_pleft = = pcur) (PARENT-&GT;_BF)--;

            Else (PARENT-&GT;_BF) + +; if (PARENT-&GT;_BF = = PARENT-&GT;_BF = 1 | | parent->_bf = 1)//parent is a leaf node, the balance factor may be 1 or 1 return TR after inserting the node     Ue                                              At this point the height of the tree does not change, the tree is still the AVL tree else if (PARENT-&GT;_BF = = 0)//parent only the left child or only the right child, after its null pointer field inserted a node, the balance factor is 0, {
                At this point the height of the tree may have changed, we have to determine whether its ancestor node balance pcur = parent;
            Parent = pcur->_pparent;
                } else {//does not satisfy the balance tree, to do the rotation if (PARENT-&GT;_BF = = 2)//Right Sub-tree {if (PCUR-&GT;_BF = = 1)//Right _rotatel (parent);//L-Adjustment El
                    Se//left _rotaterl (parent),//right-handed and left-handed} else//left dial hand tree { if (PCUR-&GT;_BF = =-1)//left _rOtater (parent);
                else//right _ROTATELR (parent);
    }}} return true;  
    } bool Isbalance () {return _isbalance (_proot);  
        } void Inorder () {_inorder (_proot);  
    cout << Endl;  
        } Protected:bool _isbalance (node* root) {if (NULL = = root) return true;  
        int BF = _height (root->_pright)-_height (Root->_pleft);  
         if (bf = = ROOT-&GT;_BF) return true;

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.