C++ - AVL平衡二叉树

目录

AVL树的概念与特点

定义与特点

平衡因子与高度

AVL树的操作

AVL树的旋转

AVL树的结构(这里开始讲代码)

 AVL树的插入

         更新平衡因子

 旋转

        右单旋

 左单旋

 左右双旋

 右左双旋

AVL树的查找 

 AVL的平衡检测

 AVL树的删除


AVL树的概念与特点

        AVL树是一种自平衡的二叉查找树,平衡二叉树且搜索二叉树

定义与特点

        定义

        AVL树是最先发明的自平衡二叉查找树。在AVL树中,任何节点的两个子树的高度最大差别为1,所以它也被称为高度平衡树

        特点

  • 它本身首先是一棵二叉搜索树。
  • 带有平衡条件:每个节点的左右子树的高度之差的绝对值(平衡因子)最多为1。
  • AVL树的基本操作一般涉及运做同在不平衡的二叉查找树所运做的同样的算法,但是要进行预先或随后做一次或多次所谓的“AVL旋转”。

平衡因子与高度

        平衡因子

        每个节点都有一个平衡因子,任何节点的平衡因子等于其右子树的高度减去左子树的高度,也就是说,任何节点的平衡因子等于0/1/-1。虽然AVL树并不必须要平衡因子,但是有了平衡因子可以更方便观察和控制树是否平衡。

        高度要求

        AVL树是高度平衡搜索二叉树,通过控制高度差去控制平衡。要求高度差不超过1,而不是高度差为0,是因为在某些情况下(如节点数为2或4时),高度差最好就是1,无法做到高度差为0。

AVL树的操作

        插入操作

  • 插入一个值按二叉搜索树规则进行插入。
  • 新增节点以后,只会影响祖先节点的高度,也就是可能会影响部分祖先节点的平衡因子。所以需要更新从新增节点到根节点路径上的平衡因子。
  • 在更新平衡因子的过程中出现不平衡,需要对不平衡子树进行旋转。旋转后本质调平衡的同时,降低了子树的高度,不会再影响上一层,所以插入结束。

        删除操作

  • 可以通过把要删除的节点向下旋转成一个叶子节点,接着直接剪除这个叶子节点来完成。
  • 因为在旋转成叶子节点期间最多有logn个节点被旋转,而每次AVL旋转耗费恒定的时间,所以删除处理在整体上耗费O(logn)时间。

        查找操作

  • 在AVL树中查找同在一般二叉搜索树(BST)中一样,所以耗费O(logn)时间。
  • AVL树总是保持平衡的,不需要特殊的准备,树的结构不会由于查询而改变(与伸展树查找相对立,它会因为查找而变更树结构)。

AVL树的旋转

        假设由于在二叉排序树上插入节点而失去平衡的最小子树根节点的指针为a(即a是离插入点最近,且平衡因子绝对值超过1的祖先节点),则失去平衡后进行的规律可归纳为下列四种情况:

  • 单向右旋平衡处理LL:由于在a的左子树根节点的左子树上插入节点,a的平衡因子由1增至2,致使以a为根的子树失去平衡,则需进行一次右旋转操作。
  • 单向左旋平衡处理RR:由于在a的右子树根节点的右子树上插入节点,a的平衡因子由-1变为-2,致使以a为根的子树失去平衡,则需进行一次左旋转操作。
  • 双向旋转(先左后右)平衡处理LR:由于在a的左子树根节点的右子树上插入节点,a的平衡因子由1增至2,致使以a为根的子树失去平衡,则需进行两次旋转(先左旋后右旋)操作。
  • 双向旋转(先右后左)平衡处理RL:由于在a的右子树根节点的左子树上插入节点,a的平衡因子由-1变为-2,致使以a为根的子树失去平衡,则需进行两次旋转(先右旋后左旋)操作。

AVL树的结构(这里开始讲代码)

首先,它的底层是搜索二叉树的基础上进行的,所以会像搜索二叉树

struct AVLTreeNode
{
	AVLTreeNode(const T& data = T())
		: _pLeft(nullptr)
		, _pRight(nullptr)
		, _pParent(nullptr)
		, _data(data)
		, _bf(0)
	{}

	AVLTreeNod
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值