avl

AVL树

随声附和 提交于 2019-11-29 05:49:39
AVL树是一颗平衡二叉查找树,平衡指左子树和右子树高度差为1,因此他的高度始终为 O(logN) 级别。 一.创建:需要从上往下进行判断这个树是否失衡。如果失衡的话需要进行调整: 1.找到失衡的节点进行调整:如图 此时是个平衡二叉查找树,我们要插入节点1的话,变成上图的样子,已经失衡了我们需要进行右旋转,所谓右旋转指的是距离差距节点最近的失衡节点变成了它子节点的右孩子。于是: 这样又变成了avl树。如果节点3本身具有右节点a3那么把a3放在5号节点之后。左旋转和右旋转是相反的操作。 2.左旋右旋无法变成avl树的时候我们需要左右互相使用: 来源: https://www.cnblogs.com/snailbuster/p/11457226.html

AVL-平衡二叉树的原理和实现

眉间皱痕 提交于 2019-11-28 21:47:25
一、简介   本文将通过图解和代码详细讲解AVL平衡二叉树的性质及失衡和再平衡的内容。在看本文之前希望大家具备二分搜索树的相关知识。或移步 《二分搜索树》 了解二分搜索树。 二、平衡二叉树   前面关于二分搜索树的文章,最后分析了在极端情况下,二分搜索树会退化为一个链表,那为了避免这种情况的发生,AVL平衡二叉树应运而生。   平衡二叉树的定义: 1 平衡二叉树是一颗二分搜索树,及平衡二叉树满足二分搜索树的所有性质 2 平衡二叉树要求任意一个节点的左右子树的高度差不能超过1   对于第一点应该挺容易理解的,对于第二点,我们要做一点解释。对于高度差,有一个专有名词平衡因子。    平衡因子 :左子树的高度减去右子树的高度,及B = B左 - B右。由平衡二叉树的定义可知,平衡因子的取值只可能为0,1,-1。0:左右子树等高。1:左子树比较高。-1:右子树比较高。如下图    高度: 一般的我们取叶子节点的高度值为1,任意一个节点的高度值取左右子树比较高的那个孩子节点的高度值然后加1。比如上图1中20这个节点的高度值,显然左子树比较高,所以H20 = H10 + 1;依次类推,H10 = H6(或者H14) + 1 = 2;所以H20 = 3;   上图1的树的各个节点的高度,如下图1所示。各个节点的平衡因子如下图2红色数字所示。所以根据定义,各个节点的左右子树的高度差不能超过1

AVL树(二叉平衡树)详解与实现

血红的双手。 提交于 2019-11-28 12:34:35
AVL树概念 前面学习 二叉查找树 和 二叉树的各种遍历 ,但是其 查找效率不稳定 (斜树),而二叉平衡树的用途更多。查找相比稳定很多。( 欢迎关注 数据结构专栏 ) AVL树是 带有平衡条件的二叉查找树 。这个平衡条件必须要 容易保持 。而且要保证它的深度是O(logN). AVL的条件是左右树的高度差( 平衡因子 )不大于1;并且它的每个子树也都是平衡二叉树。 对于平衡二叉树的最小个数, n0=0 ; n1=1 ; nk=n(k-1)+n(k-2)+1 ;(求法可以类比斐波那契!) 难点:AVL是一颗二叉排序树,用什么样的规则或者规律让它能够在 复杂度不太高 的情况下 实现动态平衡 呢? 不平衡概况 如果简单的以单节点看,大致有上面 四种 情形,并且他们的最后结果也是有的有所相近。只是:上下会变动。 该在左面的还在左面,改在右面的还在右面 。 这只是针对在底部,对于可能出现的平衡要首先搞清楚: 所以针对四种不平衡, 可能出现在底部,也可能出现在头,也可能出现在某个中间节点导致不平衡。 而我们只需要研究其首次不平衡点, 解决之后整棵树即继续平衡 。当然,在实际解决肯定会带上 递归 的思想解决问题。 # 四种平衡旋转方式 RR平衡旋转(左单旋转) 出现这种情况的原因是节点的 右侧的右侧较深 这时候 不平衡节 点需要 左旋 。再细看过程。 再左旋的过程中, root(oldroot)

自平衡方式--旋转

耗尽温柔 提交于 2019-11-28 08:27:57
关键字:AVL、插入、删除 前言:  平衡二叉树和AVL树这两个概念的区分:平衡二叉树是对这样一种数据结构的定义,是一种描述;而AVL树则是对这样子一种数据结构的实现。同红黑树和B树等一样,都是对这样一种结构的实现,同时都是具有自平衡特性的。  AVL树是最早的被发明的自平衡二叉树 1、定义:   ①左子树和右子树都是AVL树   ②左子树和右子树的高度差不能超过1 2、性质:   ①一棵n个结点的AVL树的其高度保持在0(log2(n)),不会超过3/2log2(n+1)   ②一棵n个结点的AVL树的平均搜索长度保持在0(log2(n)).   ③一棵n个结点的AVL树删除一个结点做平衡化旋转所需要的时间为0(log2(n)). 3、AVL树添加新节点: (1)找到插入节点的位置,然后插入节点 (2)"插入修复": 首先确定不平衡起始点,然后按照自平衡的旋转策略(左旋、右旋)进行相应的操作(详见: 自平衡方式--旋转 ) 4、AVL树删除节点: (1)找到替换节点。   ①如果删除节点是叶子节点,那么替换节点就是NULL;   ②如果删除节点有一个子节点,那么替换节点就是其左子节点或者右子节点;(如果删除节点有一个子节点,那么这个子节点肯定是叶子节点,要满足AVL严格平衡的特性。)   ③如果删除节点有两个孩子,那么中序遍历的后继节点就作为替换节点 (2

AVL 树介绍

£可爱£侵袭症+ 提交于 2019-11-27 07:41:06
文章目录 AVL 树引出 AVL 树的定义 AVL 树的插入 AVL 树的旋转(4种) 1. 新节点插入较高左子树的左侧---左左:右单旋 2. 新节点插入较高右子树的右侧---右右:左单旋 3. 新节点插入较高左子树的右侧---左右:先左单旋再右单旋 4. 新节点插入较高右子树的左侧---右左:先右单旋再左单旋 AVL 树性能分析 AVL 树引出 二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查找元素相当于在顺序表中搜索元素,效率低下。因此,两位俄罗斯的数学家G.M.Adelson-Velskii和E.M.Landis在1962年发明了一种解决上述问题的方法:当向二叉搜索树中插入新结点后,如果能保证每个结点的左右子树高度之差的绝对值不超过1(需要对树中的结点进行调整),即可降低树的高度,从而减少平均搜索长度 一棵 AVL 树,或者是空树,或者具有以下性质的二叉搜索树 左子树和右子树都是 AVL 树 左右子树的高度差(也叫做平衡因子)绝对值不超过1(-1/0/1) 如果一棵二叉搜索树是高度平衡的就称它为 AVL 树,如果它有 n 个节点,它的高度为O(logN),查找的时间复杂度为O(logN) AVL 树的定义 template < class T > struct AVLTreeNode { AVLTreeNode ( const T &

二叉查找树(查找、插入、删除)——C语言

落爺英雄遲暮 提交于 2019-11-27 06:10:17
AVL树 平衡二叉查找树(Self-balancing binary search tree)又被称为AVL树( AVL树是根据它的发明者G. M. A delson- V elskii和 E. M. L andis命名的 ),是在二叉查找树的基础上一个优化版本 AVL树的特点: 1.本身首先是一棵二叉查找树 2.带有平衡条件:每个结点的左右子树的高度之差的绝对值不超过1, 也就是说,AVL树,本质上是带了平衡功能的二叉查找树 如果读者关于二叉查找树还不了解可以看一下这篇随笔: 二叉查找树(查找、插入、删除) AVL树的作用 AVL树解决了二叉查找树可能出现的极端情况,对于一般的二叉搜索树(Binary Search Tree),其期望高度(即为一棵平衡树时)为log2n,其各操作的时间复杂度(O(log2n))同时也由此而决定,但是在某些极端情况下 (如在插入的序列是有序的时),二叉搜索树将退化成近似链或链,此时,其操作的时间复杂度将退化成线性的,即O(n)。我们可以通过随机化建立二叉搜索树来尽量的避免这种情况,但是在进行了多次的操作之后,例如在在删除时, 我们总是选择将待删除节点的后继代替它本身,这样就会造成总是右边的节点数目减少,以至于树向左偏沉。这同时也会造成树的平衡性受到破坏,使得它的操作时间复杂度增加 例如下面这种情况: AVL树的特性让二叉搜索树的节点实现平衡

AVL树删除操作

不羁岁月 提交于 2019-11-25 21:30:33
AVL树的删除操作: 删除操作分几种情况: 1.如果要删除的节点时NULL 则直接返回NULL。 2.如果删除的节点不为NULL,需要判断要删除的值是否等于当前节点。如果大于,则递归去删除当前节点的右子树。 3.如果删除的节点不为NULL,且要删除的值小于当前节点的值,则递归删除当前节点的左子树。 4.如果删除的节点不为NULL,如果要删除的值等于当前节点的值,则找到右子树的最小节点替换掉当前节点或者找到左子树的最大节点替换掉当前节点。 #include <iostream> struct AVLNode { int value; int height; AVLNode *left; AVLNode *right; }; // 计算节点的高度 int Height(AVLNode *node) { if (node == 0) return 0; else return node->height; } int Max(int a, int b) { return a > b ? a : b; } AVLNode * FindMin(AVLNode *p) { if (p == 0) return 0; if (p->left == 0) return p; else return FindMin(p->left); } // 单方向的左旋操作 AVLNode *