栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > Java

AVL 树

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

AVL 树

文章目录
    • AVL树的概念
    • AVL树节点的定义
    • AVL树的插入(难点)

AVL树的概念

一棵AVL树或者是空树,或者是具有以下性质的二叉搜索树:

它的左右子树都是AVL树
左右子树高度之差(简称平衡因子)的绝对值不超过1(-1/0/1)


如果一棵二叉搜索树是高度平衡的,它就是AVL树。如果它有n个结点,其高度可保持在

O ( l o g 2 n ) O(log_2 n) O(log2​n),搜索时间复杂度O( l o g 2 n log_2 n log2​n)。

AVL树节点的定义
template
struct AVLTreeNode
{
	AVLTreeNode* _left;
	AVLTreeNode* _right;
	AVLTreeNode* _parent;
	pair _kv;
	
	//平衡因子
	int _bf;


	AVLTreeNode(const pair& kv)
		:_left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _kv(kv)
		,_bf(0)
	{}
};
AVL树的插入(难点)

AVL树就是在二叉搜索树的基础上引入了平衡因子,因此AVL树也可以看成是二叉搜索树。那么AVL树的插入过程可以分为两步:

  1. 按照二叉搜索树的方式插入新节点
    搜索二叉树
  2. 调整节点的平衡因子

情况1:新节点插入较高左子树的左侧-进行右单旋

void RotateR(Node* cur)
	{
		Node* SubL = cur->_left;
		Node* SubLR = SubL->_right;
		//     60
		//  30
		//10
		Node* parent = cur->_parent;

		cur->_left = SubLR;
		if(SubLR)
			SubLR->_parent = cur;


		SubL->_right = cur;
		cur->_parent = SubL;


		if (parent == nullptr)
		{
			_root = SubL;
			SubL->_parent = parent;
		}
		else
		{
			if (parent->_left == cur)
			{
				parent->_left = SubL;
				SubL->_parent = parent;
			}
			else if (parent->_right == cur)
			{
				parent->_right = SubL;
				SubL->_parent = parent;
			}
			else
			{
				assert(false);
			}
		}

	}

情况2:新节点插入较高右子树的右侧-进行左单旋

void RotateL(Node* cur)
	{
		Node* SubR = cur->_right;
		Node* SubRL = SubR->_left;
		//10
		//  30
		//	   60
		Node* parent = cur->_parent;

		cur->_right = SubRL;
		if (SubRL)
			SubRL ->_parent = cur;


		SubR->_left = cur;
		cur->_parent = SubR;


		if (parent == nullptr)
		{
			_root = SubR;
			SubR->_parent = parent;
		}
		else
		{
			if (parent->_left == cur)
			{
				parent->_left = SubR;
				SubR->_parent = parent;
			}
			else if (parent->_right == cur)
			{
				parent->_right = SubR;
				SubR->_parent = parent;
			}
			else
			{
				assert(false);
			}
		}
	}

情况三: 新节点插入较高左子树的右侧-先左单旋再右单旋
1.在b树插入新节点

2.在c树插入新节点

3.60即为插入的新节点

以上三种情况都是先左旋再右旋,区别:旋转完之后节点的平衡因子不同

		Node* node = cur->_right;
		int bf = node->_bf;
		RotateL(cur);
		RotateR(parent);

		if (bf == 0)
		{
			parent->_bf = cur->_bf = node->_bf = 0;
		}
		else if (bf == -1)
		{
			cur->_bf = node->_bf = 0;
			parent->_bf = 1;

		}
		else if (bf == 1)
		{
			parent->_bf = node->_bf = 0;
			cur->_bf = -1;
		}

情况4:新节点插入较高右子树的左侧-先右单旋再左单旋

与情况三相同,60的平衡因子会影响旋转完之后30 60 90 的平衡因子

	Node* node = cur->_left;
	int bf = node->_bf;
	RotateR(cur);
	RotateL(parent);
	if (bf == 0)
	{
		parent->_bf = cur->_bf = node->_bf = 0;
	}
	else if (bf == 1)
	{
		cur->_bf = node->_bf = 0;
		parent->_bf = -1;
	}

	else if (bf == -1)
	{
		node->_bf = parent->_bf = 0;
		cur->_bf = 1;
	}
转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/1039610.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号