AVL Tree | Set 1 (Insertion)

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.

所有结点的左子树和右子树的高度只差不能大于1;

Insertion
To make sure that the given tree remains AVL after every insertion, we must augment the standard BST insert operation to perform some re-balancing. Following are two basic operations that can be performed to re-balance a BST without violating the BST property (keys(left) < key(root) < keys(right)).

  1. Left Rotation
  2. Right Rotation
T1, T2 and T3 are subtrees of the tree 
rooted with y (on the left side) or x (on 
the right side)           
     y                               x
    / \     Right Rotation          /  \
   x   T3   - - - - - - - >        T1   y 
  / \       < - - - - - - -            / \
 T1  T2     Left Rotation            T2  T3
Keys in both of the above trees follow the 
following order 
 keys(T1) < key(x) < keys(T2) < key(y) < keys(T3)
So BST property is not violated anywhere.

implementation
Following is the implementation for AVL Tree Insertion. The following implementation uses the recursive BST insert to insert a new node. In the recursive BST insert, after insertion, we get pointers to all ancestors one by one in a bottom-up manner. So we don’t need parent pointer to travel up. The recursive code itself travels up and visits all the ancestors of the newly inserted node.

  1. Perform the normal BST insertion.
    向一个正常的BST中插入结点

  2. The current node must be one of the ancestors of the newly inserted node. Update the height of the current node.
    现有的结点必须是插入结点的祖先,更新现有结点的高度

  3. Get the balance factor (left subtree height – right subtree height) of the current node.
    得到现有结点的平衡因子

  4. If balance factor is greater than 1, then the current node is unbalanced and we are either in Left Left case or left Right case. To check whether it is left left case or not, compare the newly inserted key with the key in left subtree root.

如果平衡因子大于1,那么现有结点是不平衡的,我们要不进行左左旋转,或者进行左右旋转;

  1. If balance factor is less than -1, then the current node is unbalanced and we are either in Right Right case or Right-Left case. To check whether it is Right Right case or not, compare the newly inserted key with the key in right subtree root.

如果平衡因子小于-1,那么现有结点是不平衡的,我们要不进行右右旋转,或者进行右左旋转;

// C++ program to insert a node in AVL tree
#include<iostream>
#include<stdio.h>
using namespace std;
int cnt=0;
struct Node{
    int key;
    Node *left,*right;
    int height;
    Node():key(0),left(NULL),right(NULL),height(1){};
};

// A utility function to get maximum of two integers
int max(int a,int b){
    return (a>b)?a:b;
}
// A utility function to get the height of the tree
int getheight(Node *root){
    if(root==NULL){
        return 0;
    }else
        return root->height;
}
/* Helper function that allocates a new node with the given key and NULL left and right pointers. */
Node *newNode(int value){
    Node *leaf=new Node();
    leaf->key=value;
    return leaf;
}
/*c) left left Case
         y                                    x
        /                                   /   \
       x          Right Rotate (x)               y
        \         - - - - - - - - ->            /
        T2                                     T2

 
A utility function to right rotate subtree rooted with y.
 See the diagram given above. */
Node *rightRotate(Node *y){
    cnt++;
    Node *x=y->left;
    Node *T2=x->right;
    // Perform rotation
    x->right=y;
    y->left=T2;
    // Update heights
    y->height=max(getheight(y->left),getheight(y->right))+1;
    x->height=max(getheight(x->left),getheight(x->right))+1;
    // Return new root
    return x;
}
// A utility function to left rotate subtree rooted with x.
Node *leftRotate(Node *x){
    cnt++;
    Node *y=x->right;
    Node *T2=y->left;
    // Perform rotation
    y->left=x;
    x->right=T2;
    // Update heights
    x->height=max(getheight(x->left),getheight(x->right))+1;
    y->height=max(getheight(y->left),getheight(y->right))+1;
    // Return new root
    return y;
}
// Get Balance factor of node root
int getBalance(Node *root){
    if(root==NULL){return 0;}
    return getheight(root->left)-getheight(root->right);
}
// Recursive function to insert a key in the subtree rooted with node
//and  returns the new root of the subtree.
Node *insert(Node *root,int value){
      /* 1. Perform the normal BST insertion */
    if(root==NULL){return newNode(value);}
    if(value<root->key){
        root->left=insert(root->left,value);
    }else if(value>root->key){
        root->right=insert(root->right,value);
    }else return root;                      // Equal keys are not allowed in BST
    /* 2. Update height of this ancestor node */
    printf("key=%d,height=%d\n",root->key,root->height);
    root->height=1+max(getheight(root->left),getheight(root->right));
    /* 3. Get the balance factor of this ancestor 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&&value<root->left->key){
        return rightRotate(root);
    }
    // Right Right Case
    if(balance<-1&&value>root->right->key){
        return leftRotate(root);
    }
    // Left Right Case
    if(balance>1&&value>root->left->key){
        root->left=leftRotate(root->left);
        return rightRotate(root);
    }
    // Right Left Case
    if(balance<1&&value<root->right->key){
        root->right=rightRotate(root->right);
        return leftRotate(root);
    }
    /* return the (unchanged) node pointer */
    return root;
}

// A utility function to print preorder traversal of the tree.
// The function also prints height of every node
void preOrder(Node *root){
    if(root==NULL){
        return;
    }
    printf("%d ",root->key);
    preOrder(root->left);
    preOrder(root->right);
}

// Driver Code
int main(){
    Node *root=NULL;
    /* Constructing tree given in the above figure */
    root = insert(root, 10);
    root = insert(root, 20);
    root = insert(root, 30);
    root = insert(root, 40);
    root = insert(root, 50);
    root = insert(root, 25);
    cout << "Preorder traversal of the constructed AVL tree is \n";
    preOrder(root);
    cout<<endl<<cnt<<endl;
    return 0;
}


key=10,height=1
key=20,height=1
key=10,height=2
key=30,height=1
key=20,height=2
key=40,height=1
key=30,height=2
key=20,height=3
key=30,height=1
key=40,height=2
key=20,height=3
Preorder traversal of the constructed AVL tree is 
30 20 10 25 40 50 
4
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值