平衡二叉树AVL的创建

①定义
平衡二叉树:对于二叉树中任意节点,左子树的高度和右子树的高度差的绝对值不超过1.还有一点,平衡二叉树是一种位置高度平衡的二叉搜索树。二叉搜索树详见上一篇博客。
②平衡二叉树的四种旋转
平衡二叉树的创建在于对于插入节点后,需要对插入之后的树进行维护高度。
维护高度的方法有四种:左旋,右旋,左右旋,右左旋。

树的结构
typedef struct Node *node;
struct Node{     
    node left;     
    node right;    
    int data;
};

四种维护高度的方法代码:分别对应的代码如下

void left(node root){ //左旋,返回的是对于root左旋后的新的根节点
    node tmp = root->left;    
    root->left = tmp->right;    
    tmp->right = root;    
    return tmp;
}
void right(node root){//同理,右旋
    node tmp = root->left;    
    root->right = tmp->left;    
    tmp ->left = root;
    return tmp;
}
node left_right(node root){ //左右选,可以理解为先对左孩子进行右旋矫正之后在进行根节点左旋
    root->left = right(root->left);    
    return left(root);
    }
node right_left(node root){//同理,右左旋
    root->right = left(root->right);    
    return right(root);
}

在了解四种维护高度的代码之后,具体原因以及旋转机制,详见自己课本(嘿嘿!)
③节点的插入
对于AVL树的插入,与二叉搜索树的插入原理相同,只是多了维护高度的步骤,代码如下:

int get_high(node root){ //简单的遍历二叉树进行获取节点root的高度
    if(root == NULL)         
        return 1;
    else        
        return max(get_high(root->left), get_high(root->right)) + 1;
}
node Insert(node root,int x){
    if(!root){        
	    node tmp = (node)malloc(sizeof(struct Node));        
	    tmp->left = NULL;        
	    tmp->right = NULL;        
	    tmp ->data= x;        
	    root = tmp;    
	}else if(x > root->data){
	    root->right = Insert(root->right, x);        
	    if(get_high(root->left) - get_high(root->right) == -2)
	    {//若等于 -2,说明插入右子树的节点导致二叉树不平衡            
	        if(x > root->right->data){  //如果是插入右孩子的右边导致不平衡,则直接右旋              
	            root = right(root);            
	        }else if(x < root->right->data){//反之,则是插入右孩子的左孩子导致不平衡
	            root = right_left(root);//直接右左旋
	        }        
	     }    
	 }else if(x < root->data){ //同上 右子树的高度维护
	     root->left = Insert(root->left, x);
	     if(get_high(root->left) - get_high(root->right) == 2){
	            if(x > root->left->data){
	               root = left_right(root);            
	            }else if(x < root->left->data){
	               root = left(root);            
	            }        
	      }    
	  }     
    return root;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值