C语言实现平衡二叉树

1.平衡二叉树的定义

平衡二叉树,简称平衡树(AVL树)—-树上任一结点的左子树和右子树的高度之差不超过1.
结点的平衡因子=左子树高-右子树高,值只可能是-1,0,1.
类型定义

//平衡二叉树结点
typedef struct AVLNode{
	int key;		//数据域
	int balance;	//平衡因子
	struct AVLNode *lchild, *rchild;
}AVLNode, *AVLTree;

2.平衡二叉树的插入

插入结点时,首先按照二叉排序树处理,若插入结点后破坏了平衡二叉树的特性,需对平衡二叉树进行调整。

3.平衡二叉树的调整

调整方法:找到离插入结点最近且平衡因此绝对值超过1的祖先结点,以该结点为根的子树称为最小不平衡子树,可讲重新平衡的范围局限于这颗子树。
调整最小不平衡子树:
LL:在A的左孩子的左子树中插入导致不平衡
RR:在A的右孩子的右子树中插入导致不平衡
LR:在A的左孩子的右子树中插入导致不平衡
RL:在A的右孩子的左子树中插入导致不平衡
1)LL平衡旋转(右单旋转)。由于在结点A的左孩子(L)的左子树(L)上插入了新结点,A的平衡因子由1增至2,导致以A为根的子树失去平衡,需要一次向右上旋转代替A成为根结点,将A结点向右下旋转成为B的右子树的根结点,而B的原右子树则作为A结点的左子树。
在这里插入图片描述
2)RR平衡旋转(左单旋转)。由于在结点A的右孩子(R)的右子树(R)上插入了新结点,A的平衡因此由-1减至-2,导致以A为根的子树失去平衡,需要一次向左的旋转操作。将A的右孩子B向上旋转代替A成为根结点,将A结点向左下旋转成为B的左子树的根结点,而B的原左子树则作为A结点的右子树。
在这里插入图片描述
3)LR平衡旋转(先左后右双旋转)。由于A的左孩子(L)的右子树(R)上插入新结点,A的平衡因此由1增至2,导致以A为根的子树失去平衡,需要进行两次旋转操作,先左旋转后右旋转。先将A结点的左孩子B的右子树的根结点C向左上旋转提升到B结点的位置,然后再把C结点向右上旋转提升到A结点的位置。
在这里插入图片描述
4)RL平衡旋转(先右后左双旋转)。由于在A的右孩子(R)的左子树(L)上插入新结点,A的平衡因子由-1减至-2,导致以A为根的子树失去平衡,需要进行两次旋转操作,先右旋转后左旋转。先将A结点的右孩子B的左子树的根结点C向右上旋转提升到B结点的位置,然后再把C结点向左上旋转提升到A结点的位置。
在这里插入图片描述
总结:
A.只有左孩子才能右上旋:
实现f向右下旋转,p向右上旋转:
其中f是爹,p为左孩子,gf为他爹
a.f->lchild=p->rchild;
b.p->rchild=f;
c.gf->lchild/rchild=p;

B.实现f向左下旋转,p向左上旋转:
其中f是爹,p为右孩子,gf为他爹
a.f->rchild=p->lchild;
b.p->lchild=f;
c.gf->lchild/rchild=p;

LL:在A的左孩子的左子树中插入导致不平衡,调整:A的左孩子结点右上旋
RR:在A的右孩子的右子树中插入导致不平衡,调整:A的右孩子结点左上旋
LR:在A的左孩子的右子树中插入导致不平衡,调整:A的左孩子的右孩子先左上旋再右上旋
RL:在A的右孩子的左子树中插入导致不平衡,调整:A的右孩子的左孩子,先右上旋后左上旋

4.查找效率分析

若树高为h,则最坏情况下,查找一个关键字最多需要对比h次,即查找操作的时间复杂度不可能超过O(h)
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值