关于调节AVL树的平衡(左右旋)

AVL树是平衡二叉搜索树,保持左右子树高度差不超过1。插入节点可能导致不平衡,需要通过旋转进行调整。右单旋发生在节点的左子树过深,左单旋反之。双旋分为先左后右和先右后左,以中间节点或底部节点为旋转轴。具体实现包括节点更新和父节点指针调整。
摘要由CSDN通过智能技术生成

关于调节AVL树的平衡(左右旋)

AVL树:具有以下性质的二叉搜索树:左右孩子也都是AVL树,并且左右子树高度差的绝对值不超过1(平衡因子为-1,0,1中的一个)。
平衡因子:该节点右子树和左子树的高度差,这个数字即是这个结点的平衡因子。

也就是说:AVL树是在BST树的基础上增加了平衡因子的概念,变成了平衡二叉搜索树。


关于结点类型和树的设计:

typedef int KeyType;
typedef struct AVLNode{
	AVLNode*left;
	AVLNode*right;
	AVLNode*parent;
	KeyType key;
	int balance;
}AVLNode;
typedef struct AVLTree{
	AVLNode* head;
	KeyType cursize;
}AVLTree;

AVL树的结点插入
与BST树的插入方法相同,但是因为平衡因子的加入,当插入结点时,可能是AVL的树的平衡性发生了变化,所以我们需要进行平衡调整。从插入结点的位置开始向根节点回溯,检查各结点的平衡因子,找到不平衡的结点的时候,沿刚才回溯的路径往下取两个结点

  • 如果三个结点构成一个条直线,并且方向向左下方,进行右单旋
  • 如果三个结点构成一个条直线,并且方向向右下方,进行左单旋
  • 如果三个结点构成折线先左后右,进行左右双旋
  • 如果三个结点构成折线先右后左,进行右左双旋

右单旋

在C的左孩子增加结点D,从D开始往根节点回溯检查平衡因子,发现A结点的平衡因子为-2,这个AVL树失去平衡,按刚才的路径往下找三个结点:A B C,三个结点构成一个方向是左下方的直线,所以,以B为轴进行右单旋。

  • 将ptr的左孩子作为newroot
    newroot->parent=ptr->parent
    在这里插入图片描述
  • 将ptr的左孩子指向newroot的右孩子
    ptr->left=newroot->right
    ①当new的右孩子不为空的时候,需要将newroot的右孩子的parent指向ptr
    在这里插入图片描述
  • 将newroot的右孩子指向ptr
    newroot->right=ptr
    ①当ptr是树的根节点的时候,需要将头结点的parent指向newroot
    ②不是根节点的时候,看ptr是ptr父结点的左孩子还是右孩子,将newroot接回去,这里可能就有人问了,第一步的时候不是已经接回去了嘛?为什么还接一次?因为结点是双向的
    ③再把ptr的parent指向newroot
    在这里插入图片描述
  • 完成
    在这里插入图片描述
    具体代码实现:
void RoteteRight(AVLTree*ptree, AVLNode*ptr)
{
    //1 将ptr的左孩子作为newroot
    AVLNode *newroot = ptr->left;
	newroot->parent = ptr->parent;
	//2  将ptr的左孩子指向newroot的右孩子
	ptr->left= newroot->right;
	if (newroot->right != NULL)
	{
		newroot->right->parent = ptr;
	}
	//3   将newroot的右孩子指向ptr
	newroot->right = ptr;
	if (ptree->head->parent == ptr) //如果ptr是树的根节点
	{
		ptree->head->parent = newroot;//将头结点的parent指向newroot
	}
	else
	{
	     //看ptr是它父结点的左孩子还是右孩子
		if (ptr = ptr->parent->left)
		{
			ptr->parent->left = newroot;
		}
		else
			ptr->parent->right = newroot;
	}
	ptr->parent = newroot;
}

左单旋
思路和右单旋是相同的,相对操作时镜像的。


单旋以三个结点中的第二个为旋转轴
双旋以最下面的结点为旋转轴(两次旋转都已这个结点为轴)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值