【数据结构】AVL树(二叉搜索平衡树)

一、引入AVL树

AVL树是二叉搜索树的升级版,是为了优化整个二叉树的结构并且提高查找速率的一棵特殊的二叉搜索树。平衡二字体现了该树会对插入/删除的结点后进行自动“平衡”(通过旋转进行实现)。

二、AVL树的要求

平衡状态: 当前结点的右子树深度 - 左子树深度 == -1 or 0 or 1

三、AVL树结构设计

AVL.h

#ifndef AVL_H
#define AVL_H
using ElemType = int;
typedef struct AVLNode
{
	ElemType key;
	AVLNode* leftchild;
	AVLNode* rightchild;
	AVLNode* parent;
	int balance;
}AVLNode, *AVLTree;

四、旋转

当插入结点时,会出现以下情况:使树失衡,对此有两种应对策略(实质上都是旋转),通过旋转能够对失衡的树进行再次平衡

在这里插入图片描述

五、单左旋

(1)单左旋三大关键步骤

在这里插入图片描述

(2)单左旋完整过程

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(3)单左旋代码
//单左旋
/*
* root是根节点
* ptr指向即将左旋的旧根
*/
void RotateLeft(AVLTree& root, AVLNode* ptr)
{
	AVLNode* newroot = ptr->rightchild;
	newroot->parent = ptr->parent;

	ptr->rightchild = newroot->leftchild;
	if (newroot->leftchild != nullptr)
	{
		newroot->leftchild->parent = ptr;
	}
	newroot->leftchild = ptr;
	//改变原有ptr的双亲的左右孩子指向(newroot)
	//ptr就是root
	if (ptr == root)
	{
		root = newroot;
	}
	else
	{
		if (ptr->parent->leftchild == ptr)
		{
			ptr->parent->leftchild = newroot;
		}
		else
		{
			ptr->parent->rightchild = newroot;
		}
	}
	ptr->parent = newroot;
}

六、单右旋

(1)单右旋代码
//单右旋
void RotateRight(AVLTree& root, AVLNode* ptr)
{
	AVLNode* newroot = ptr->leftchild;
	newroot->parent = ptr->parent;
	ptr->leftchild = newroot->rightchild;
	if (newroot->rightchild != nullptr)
	{
		newroot->rightchild->parent = ptr;
	}
	newroot->rightchild = ptr;
	if (ptr == root)
	{
		root = newroot;
	}
	else
	{
		if (ptr->parent->leftchild == ptr)
		{
			ptr->parent->leftchild = newroot;
		}
		else
		{
			ptr->parent->rightchild = newroot;
		}
	}
	ptr->parent = newroot;
}

六、双旋转

此时遇到以下情况单纯的使用一种旋转已经无法进行平衡,双旋转就是意味着需要用到左旋和右旋进行两次的旋转才能将失衡的树进行再次平衡。

出现以下状况时候,必须要使用双旋转进行平衡树。

(1)先右旋,再左旋

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(2)先左旋,再右旋

在这里插入图片描述

未完待续,下节通过具体实例来实现整个AVL树的搭建及插入结点分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值