AVL树----高度平衡的二叉搜索树

AVL树的定义:
一颗AVL树或者是一颗空树,或者是一颗具有下列性质的二叉搜索树:它的左子树和右子树都是一颗AVL树,并且左子树和右子树的高度之差的绝对值不超过1。

我们来对AVL树进行结构的设计:

typedef struct AVLNode
{
	AVLNode* leftchild;//左孩子
	AVLNode* rightchild;//有孩子
	AVLNode* parent;//双亲
	int data;//数据域
}AVLNode;
typedef struct
{
	AVLNode* head;//头节点
	int cursize;//当前树的节点个数
}AVLtree;

节点的平衡因子:

  • 给每个节点附加一个数字,给出该节点右子树的高度减去左子树的高度所得的高度差。这个数字即为节点的平衡因子。
  • 根据AVL树的定义,任一节点的平衡因子只能取-1,0,1三种。
  • 如果一个节点的平衡因子的绝对值大于1,则这颗二叉树就失去了平衡,不再是一个AVL树。
  • 如果一颗二叉搜索树是高度平衡的,它就称为AVL树,如果它有n个节点,其高度可保持在O(log2n),平均搜索长度也可保持在O(log2n)。

如图下图所示的高度不平衡的二叉搜索树和高度平衡的二叉搜索树:

在这里插入图片描述
平衡化旋转:

  1. 如果在一颗平衡的二叉搜索树中插入了一个新节点,造成了不平衡,此时必须调整树的结构,使其平衡化。
  2. 平衡化旋转有两类:
    单旋转(左旋和右旋)
    双旋转(左平衡和右平衡)
  3. 每插入一个新节点时,AVL树中相关节点的平衡状态就会发生改变。因此在插入一个新节点后,需要从插入位置沿通向根的路径回溯,检查各节点的平衡因子(左右子树的高度差)。
  4. 如果在某一节点发现高度不平衡,停止回溯。
  5. 从发生不平衡的节点起,沿刚才回溯的路径取直接下两层的节点。
  6. 如果这三个节点处于一条直线上,则采用单旋转进行平衡化。单旋转可按方向分为左单旋转和右单旋转,其中一个是另一个的镜像,其方向与不平衡的形状相关。
  7. 如果这三个节点处于一条折线上,则采用双旋转进行平衡化。双旋转分为先左后右和先右后左两类。

下面是两个左单旋转的例子:

在这里插入图片描述
代码如下:

void RotateLeft(AVLNode * &ptr)
{
	AVLNode* newroot = ptr->rightchild;
	newroot->parent = ptr->parent;
	ptr->rightchild = newroot->leftchild;
	if (newroot->leftchild != NULL)
	{
		newroot->leftchild->parent = ptr;

	}
	newroot->leftchild = ptr;
	ptr->parent = newroot;
	ptr = newroot;
}

右单旋转:

在这里插入图片描述
代码如下:

void RotateRight(AVLNode*& ptr)
{
	AVLNode* newroot = ptr->leftchild;
	newroot->parent = ptr->parent;
	ptr->leftchild = newroot->rightchild;

	if (newroot->rightchild != NULL)
	{
		newroot->rightchild->parent = ptr;
	}
	newroot->rightchild = ptr;
	ptr->parent = newroot;
	ptr = newroot;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值