再回首数据结构—AVL树(二)

前面主要介绍了AVL的基本概念与结构,下面开始详细介绍AVL的实现细节;

AVL树实现的关键点

  AVL树与二叉搜索树结构类似,但又有些细微的区别,从上面AVL树的介绍我们知道它需要维护其左右节点平衡,实现AVL树关键在于标注节点高度、计算平衡因子、维护左右子树平衡这三点,下面分别介绍;

标注节点高度

  从上面AVL树的定义中我们知道AVL树其左右节点高度差不能超过一,所以我们需要标注出每个节点高度;

  1、节点高度为最大的子节点高度加1,其中叶子节点高度为1;
  2、1与4叶子节点高度为1,节点3高度为节点4的高度加1,节点2高度为1与3节点中最大的高度加1;
  3、节点初始化时高度为1,当在AVL中添加与删除节点时需要维护其节点高度,在AVL添加节点后需要重新计算当前添加节点的高度;

计算平衡因子

  标注了每个节点高度后此时可以轻松算出每个节点的平衡因子,只需其节点左子树与右子树的高度差的绝对值即可;

  1、1、4叶子节:平衡因子为0
  2、节点3:右子树高度为1,左子树其高度为0,0-1绝对值为1,此节点平衡因子为1
  3、节点2:左子树高度为1,右子树高度为2,1-2绝对值为1,此节点平衡因子为1

维护左右子树平衡

  当在AVL中添加与删除节点时都可能造成AVL变成失去平衡状态使之退化为二叉搜索树,AVL中主要在添加节点与删除节点时需要维护其左右子树的平衡因子;

添加节点
  添加节点最终都是添加到叶子节点上,节点添加后其先祖节点可能出现了失去平衡的情况,需要从添加的节点开始向上维护平衡性,向上查找不平衡节点;

右旋转
  新增节点在不平衡节点左侧的左侧,同时不平衡节点左子树高度大于等于右子树高度(左子树平衡因子大于等于右子树平衡因子);

  添加节点1后第一个不平衡节点为节点3,同时节点3左子树高度大于右子树高度,此时需要不平衡节点向右旋转;

通过如下操作完成节点右旋转;

 T = 2.right
 2.right = 3
 3.left = T

左旋转
  新增节点在不平衡节点右侧的右侧,同时不平衡节点右子树高度大于等于左子树高度(右子树平衡因子大于等于左子树平衡因子);

添加节点3后,节点1失去平衡 添加节点3后第一个不平衡节点为节点1,同时节点1右子树高度大于左子树高度,此时需要不平衡节点向左旋转;

通过如下操作完成节点左旋转;

 T = 2.left
 2.left = 1
 1.right = T

先左旋转后右旋转

新增节点在不平衡节点左侧的右侧

先左旋转,变成了右旋转问题,重复上面说所的右旋转;

 T = 4.left
 Y = T.right
 Z = Y.left
 Y.left = T
 T.right = Z
 4.left = Y

先右旋转后左旋转

新增节点在不平衡节点右侧的左侧

先右旋转,变成了左旋转问题,重复上面说所的左旋转;

 T = 2.right
 Y = T.left
 Z = Y.right
 Y.right = T
 T.left = Z
 2.right = Y

删除节点

  删除节点是AVL树也可能会失去平衡,因此也需要维护AVL的平衡性;
节点的删除右这么几个步骤:
1、 要删除的节点比当前节点小时在左子树查找
2、 要删除的节点比当前节点大时在右子树查找
3、 要删除节点为当前节点且左子树为空时右子树顶上
4、 要删除节点为当前节点且右子树为空时左子树顶上
5、 要删除节点左右子树均存在时,大于当前节点的最小节点顶上
6、 更新节点高度值
7、 计算节点平衡因子
8、 进行与添加节点时一样的平衡因子维护操作

文章首发地址:Solinx
http://www.solinx.co/archives/1330

原文地址:https://www.cnblogs.com/softlin/p/10921835.html

时间: 2024-10-10 00:01:24

再回首数据结构—AVL树(二)的相关文章

数据结构&&AVL树原理、插入操作详解及实现

1.基本概念 AVL树的复杂程度真是比二叉搜索树高了整整一个数量级--它的原理并不难弄懂,但要把它用代码实现出来还真的有点费脑筋.下面我们来看看: 2.AVL树是什么? AVL树本质上还是一棵二叉搜索树(因此读者可以看到我后面的代码是继承自二叉搜索树的),它的特点是: 1. 本身首先是一棵二叉搜索树. 2. 带有平衡条件:每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1. 例如: 5              5 / \            / \ 2   6          2  

数据结构--AVL树

AVL树是高度平衡的二叉搜索树,较搜索树而言降低了树的高度:时间复杂度减少了使其搜索起来更方便: 1.性质: (1)左子树和右子树高度之差绝对值不超过1: (2)树中每个左子树和右子树都必须为AVL树: (3)每一个节点都有一个平衡因子(-1,0,1:右子树-左子树) (4)遍历一个二叉搜索树可以得到一个递增的有序序列 2.结构: 平衡二叉树是对二叉搜索树(又称为二叉排序树)的一种改进.二叉搜索树有一个缺点就是,树的结构是无法预料的.任意性非常大.它仅仅与节点的值和插入的顺序有关系.往往得到的是

数据结构--Avl树的创建,插入的递归版本和非递归版本,删除等操作

AVL树本质上还是一棵二叉搜索树,它的特点是: 1.本身首先是一棵二叉搜索树. 2.带有平衡条件:每个结点的左右子树的高度之差的绝对值最多为1(空树的高度为-1). 也就是说,AVL树,本质上是带了平衡功能的二叉查找树(二叉排序树,二叉搜索树). 对Avl树进行相关的操作最重要的是要保持Avl树的平衡条件.即对Avl树进行相关的操作后,要进行相应的旋转操作来恢复Avl树的平衡条件. 对Avl树的插入和删除都可以用递归实现,文中也给出了插入的非递归版本,关键在于要用到栈. 代码如下: #inclu

JAVA数据结构--AVL树的实现

AVL树的定义 在计算机科学中,AVL树是最先发明的自平衡二叉查找树.在AVL树中任何节点的两个子树的高度最大差别为1,所以它也被称为高度平衡树.查找.插入和删除在平均和最坏情况下的时间复杂度都是.增加和删除可能需要通过一次或多次树旋转来重新平衡这个树.AVL树得名于它的发明者G. M. Adelson-Velsky和E. M. Landis,他们在1962年的论文<An algorithm for the organization of information>中发表了它. 节点的平衡因子是

简单数据结构———AVL树

C - 万恶的二叉树 Crawling in process... Crawling failed Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 2193 Description An AVL tree is a kind of balanced binary search tree. Named after their invento

[数据结构] AVL树和AVL旋转、哈夫曼树和哈夫曼编码

1. AVL树 AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树.查找.插入和删除在平均和最坏情况下都是O(log n).增加和删除可能需要通过一次或多次树旋转来重新平衡这个树. 节点的平衡因子是它的左子树的高度减去它的右子树的高度(有时相反).带有平衡因子1.0或 -1的节点被认为是平衡的.带有平衡因子 -2或2的节点被认为是不平衡的,并需要重新平衡这个树.平衡因子可以直接存储在每个节点中,或从可能存储在节点中的子树高度计算出来. 1.2AVL旋转 AVL树的基本操作一

数据结构--AVL树的insert()的Java实现

一个AVL树是其每个节点的左子树和右子树的高度差最多差1的二叉查找树:AVL树是一种最古老的平衡查找树 上代码: package com.itany.avlshu; public class AVLTree<T extends Comparable<?super T>> { private static class AvlNode<T> { private int height; private T element; private AvlNode<T> l

自己动手实现数据结构——AVL树(C++实现)

这类教程有很多了,就用C++简单实现下以供记录和参考,以后再有补充版本. 实现了查找和插入.删除操作有些复杂,感觉个人实现的效率不是很高,以后再补充,先把做过的东西记录下来. Avl.h #ifndef __AVL_H #define __AVL_H #include<stddef.h> #include<vector> template< class T> struct AvlNode{ T data; int height; AvlNode* left; AvlNo

[javaSE] 数据结构(AVL树基本概念)

AVL树是高度平衡的二叉树,任何节点的两个子树的高度差别<=1 实现AVL树 定义一个AVL树,AVLTree,定义AVLTree的节点内部类AVLNode,节点包含以下特性: 1.key——关键字,对AVL树的节点进行排序 2.left——左子树 3.right——右子树 4.height——高度 如果在AVL树插入节点后可能导致AVL树失去平衡,具体会有四种状态: LL:左左,LeftLeft LR:左右,LeftRight RL:右左,RightLeft RR:右右,RightRight