平衡二叉树(AVL)

平衡二叉树的定义

平衡二叉树(Balance Binary Tree),简称平衡树(AVL树),树上任意结点的左子树和右子树的高度之差不超过1。

平衡因子=左子树高-右子树高

平衡二叉树结点的平衡因子的值只可能是1、-1、0。只要有任意结点的平衡因子不等于这三个值,那么二叉树不平衡。

平衡二叉树的插入

插入一个新结点,可能会破坏二叉树的平衡。

引入最小不平衡子树的概念:从插入结点往回找到第一个不平衡的结点,以该结点为根的子树就是最小不平衡子树。之后所有的操作都是针对最小不平衡子树的。

对于根结点为A的最小不平衡子树,分四种情况:

  • LL平衡旋转(右单旋转)。A的左孩子的左子树上插入了新结点,导致失衡,应进行右旋操作,将A的左孩子B向右上旋转,代替A成为根结点,将A右下旋成为B的右子树的根结点,而B的原右子树作为A的左子树。
  • RR平衡旋转(左单旋转)。A的右孩子的右子树上插入了新结点,导致失衡,应进行左旋操作,将A的右孩子B向左上旋转,代替A成为根结点,将A左下旋转成B的左子树的根结点,而B的原左子树作为A的右子树。
  • LR平衡旋转(先左后右双旋转)。A的左孩子的右子树上插入了新结点,导致失衡,这种情况需要两次旋转。将A结点的左孩子B的右子树的根结点C左上旋转提升到B的位置,再将C右上旋转提升到A的位置。
  • RL平衡旋转(先右后左双旋转)。A的右孩子的左子树上插入了新结点,导致失衡,方法类似上面的做法,将A的右孩子B的左子树的根结点C右上旋转提升到B的位置,再将C左上旋转提升到A的位置。

通过分析以上四种情况,我们可以看出:

1.只有左孩子才可以右上旋转,只有右孩子才可以左上旋转。

2.每次的操作都一定都是在最小不平衡子树当中进行的。

3.调整了最小不平衡子树使其平衡之后,该路径上的所有结点的都会恢复平衡。

查找效率分析

1.假设Nh为深度为h的平衡树中含有的最少结点数,那么可以得到N0=0,N1=1,N2=2,递推得到公式Nh=Nh-1+Nh-2+1。
2.含有N个结点的平衡二叉树最大深度为O(log2 n),平均查找长度为O(log2 n)。

附加:代码实现

#include<stdio.h>
#include<stdlib.h>
#define LH +1	/* 左高 */
#define EH 0	/* 等高 */
#define RH -1	/* 右高 */
#define TRUE 1
#define FALSE 0

/* 二叉树的二叉链表节点结构定义 */
typedef struct BiTNode
{
   
	int data;
	int bf;							/* 相对于二叉查找树,增加了平衡因子bf */
	struct BiTNode* lchild, * rchild;
} BiTNode, * BiTree;

void order(BiTree t)//中序输出  
{
   
	if (t == NULL)
		return;
	order(t->lchild);
	printf("%d ", t->data);
	order(t->rchild);
}

/* 对以p为根的二叉排序树作右旋处理 */
/* 处理之后p指向新的树根节点,即旋转处理之前的左子树的根节点 */
void R_Rotate(BiTree* p)
{
   
	/*
	  L->rchild (节点2的右孩子) 为NULL          L->rchild != NULL
	  例 :    3                                例 :  9              6
			 /										 / \            / \
			2    =>    2                            6  10   =>     5   9
		   /          / \                          / \            /   / \
		  1          1   3                        5   7          4   7  10
												 /
												4
	*/
	BiTree L;
	L = (*p)->lchild;
	(*p)->lchild = L->rchild;	/* 容易忽视,将*p的左子树的右子树作为*p的左子树(如果 L->rchild 不为空) */
	L->rchild = (*p);
	*p = L;
}

/* 对以p为根的二叉排序树作左旋处理 */
/* 处理之后 p 指向新的树根节点,即旋转处理之前的右子树的根节点  */
void L_Rotate
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值