平衡二叉树(AVL树)的插入

平衡二叉树本质也是一颗二叉查找树,只是在二叉查找树多了一个调平衡的操作而已;

ACL树的结点:

      

struct node {
	int data;
	int height;//高度,用于计算结点的平衡因子来判断该结点有没有失衡;
	node* lchild;
	node* rchild; 
};

  ACL树的插入:

平衡二叉树的插入造成的不平衡只有LL,RR,LR,RL四种类型,判断是什么类型是从root结点往后走两步,这两步上的结点是一左一右就是LR类型,左左就是LL,右右就是RR,一右一左就是RL类型

插入后就要调平衡,调平衡就两种方法,一种是左旋一种是右旋,根据类型不同选择方法也不同。

左旋:左旋root成为下一个结点temp的左孩子,被替换的左孩子成为该旋转后root结点的右孩子,root左旋会带着左孩子。

void L(node* &root){
	node* temp=root->lchild;
	root->rchild=temp->lchild;//空出temp左孩子的位置给root左旋; 
	temp->lchild=root;
	updateHeight(root);
	updateHeight(temp); 
	root=temp;
}

右旋:root右旋成为下一个结点temp的右孩子,被替换的右孩子成为旋转后root结点的左孩子,旋转会带着右孩子 

void R(node* &root){
	node* temp=root->lchild;
	root->lchild=temp->rchild;
	temp->rchild=root; 
	root=temp;
}
//ACL树的插入; 
//在左树插入改变的肯定就是左树的高度,就是LL或者LR类型,在右树插入的就是RR或者LR类型;
//是LL还是LR就要看子树的左树高还是右树高; 
void insert(node* &root,int  x){
	if(root==NULL){//找不到该结点就插入; 
		root=newNode(x);
		return ;
	}
	if(v<root->data){
		insert(root->lchild,x);
		//往左子树插入,只会改变左子树的高度,就只能是LL或者LR类型; 
		updateHeight(root);//回溯插入后,更新这层结点的高度; 
		if(getBalanceFactor(root)==2){//如果当前结点的平衡因子为2说明失衡了; 
			if(getBalanceFactor(root->lchild)==1){//LL类型,左孩子的平衡因子是1说明左孩子左树高度为2,右树高度为1,根节点左孩子的高度为3,右孩子的高度为1,所以是左边高往左边调; 
				R(root);//LL类型的根节点要右旋; 
			}else if(getBalanceFactor(root->rchild)==-1){//LR类型,右高左低; 
				L(root->lchild);//LR类型要先改变树的形状,根节点的左孩子左旋变成LL链形;
				R(root);//变成LL形后再右旋就可以改变这条链的高度; 
			}
		}
	}else {
		insert(root->rchild);
		updateHeight(root);
		if(getBalanceFactor(root)==-2){ 
			if(getBalanceFactor(root->lchild)==-1){
				L(root);//RR类型,直接左旋来降低高度; 
			}else if(getBalanceFactor(root)==1){
				R(root->rchild);//右旋成RR形;
				L(root);//左旋降低高度; 
			}
		}
	}
} 

4种类型,LL,RR,LR,RL:

LL右旋,RR左旋,LR先给temp结点左旋,成为LL类型后root再右旋,RL就是temp先右旋root再左旋。

A是插入后第一个不平衡的结点,一般只用调整该结点就能做到整棵树平衡。

1,2,3,4是该结点可能存在的孩子。

 

ACL树的建立:
 

//AVL树的建立:
node* Create(int data[ ],int n){
	node* root=NULL;
	for(int i=0;i<n;i++){
		insert(root,data);
	}
	return root;
} 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值