AVL树

  昨天突然有人问我AVL树,我以前以为自己还会,结果给人家讲着讲着就没有说清楚。今天就自己把AVL写了一遍总结一下,如果有写的不对地方欢迎大家拍砖。。。

  AVL定义:

(1)左子树和右子树的深度之差的绝对值小于等于1;

(2)左子树和右子树也是平衡二叉树;

下面的描述中需要用到平衡因子:节点的左子树深度与右子树深度之差。

要建立一颗平衡二叉树需要经过一下步骤:

(1)查找应插位置,同时记录离插入位置最近的可能失衡的节点A(寻找平衡因子不等于0)

		while(p != NULL)
		{
			if(p->bf != 0)
			{
				A = p;
				FA = fp;
			}
			fp = p;
			if(k < p->key)
				p = p->lchild;
(2)插入节点S;

 

		if(k < fp->key)
			fp->lchild = s;
		else
			fp->rchild = s;
(3)确定节点B,并修改A的平衡因子

 

		if(k < A->key)
		{
			B = A->lchild;
			A->bf += 1;
		}
		else
		{
			B = A->rchild;
			A->bf -= 1;
		}
(4) 修改从B到S路径上各结点的平衡因子

 

		p = B;
		while(p != s)
		{
			if(k < p->key)
			{
				p->bf = 1;
				p = p->lchild;
			}
			else
			{
				p->bf = -1;
				p = p->rchild;
			}
		}
(5)根据A、B的平衡因子,判断是否失衡以及失衡类型,并作相应处理。

  前面那些东西可能看起来还比较清晰,容易理解我也就不多说什么了。第(5)步比较复杂咱们单独来看~~。首先要知道平衡因子的概念,如果不知道看前面介绍。然后就是把插入过程如果失衡分成4种情况来处理。

第一种:LL型                                                                                                       旋转后:

                                                                         

		if(A->bf == 2 && B->bf == 1)                     //LL
		{
			B = A->lchild;
			A->lchild = B->rchild;
			B->rchild = A;
			A->bf = 0;
			if(FA == NULL)
				*avlt = B;
			else if(FA->lchild == A)
				FA->lchild = B;
			else
				FA->rchild = B;
			B->bf = 0;
		} 

第二种:LR型                                                                                                    

                                                                             

		else if(A->bf == 2 && B->bf == -1)               //LR
		{
			B = A->lchild;
			C = B->rchild;
			B->rchild = C->lchild;
			C->lchild = B;
			A->lchild = C->rchild;
			C->rchild = A;
			if(C->key > s->key)                     //在CL下插入s
			{
				A->bf = -1;
				B->bf = 0;
				C->bf = 0;
			}
			else if(C->key < s->key)                //在CR下插入s
			{
				A->bf = 0;
				B->bf = 1;
				C->bf = 0;
			}
			else                                    //C本身就是插入的新节点s
			{
				A->bf = 0;
				B->bf = 0;
			}
				if(FA == NULL)
				*avlt = C;
			else if(FA->lchild == A)
				FA->lchild = C;
			else
				FA->rchild = C;
		}

第三种:RL型

                                                                          

		else if(A->bf == -2 && B->bf == 1)               //RL
		{
			B = A->rchild;
			C = B->lchild;
			A->rchild = C->lchild;
			B->lchild = C->rchild;
			C->lchild = A;
			C->rchild = B;
			if(C->key > s->key)
			{
				A->bf = 0;
				B->bf = -1;
				C->bf = 0;
			}
			else if(C->key < s->key)
			{
				A->bf = 1;
				B->bf = 0;
				C->bf = 0;
			}
			else
			{
				A->bf = 0;
				B->bf = 0;
			}
			if(FA == NULL)
				*avlt = C;
			else if(FA->lchild == A)
				FA->lchild = C;
			else
				FA->rchild = C;
		}

第四种:RR型

                                                                           

		else if(A->bf == -2 && B->bf == -1)              //RR
		{
			B = A->rchild;
			A->rchild = B->lchild;
			B->lchild = A;
			A->bf = 0;
			B->bf = 0;	
			if(FA == NULL)
				*avlt = B;
			else if(FA->lchild == A)
				FA->lchild = B;
			else
				FA->rchild = B;
		}
如果大家还有什么不明白的,或者我哪有错误的希望大家指出或者给我发邮件xiyou.jike1101lw@gmail.com


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值