AVL树

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

AVL树基本信息

中文名称 AVL树 外文名称 AVL tree
含义 自平衡二叉查找树 特点 最先发明
词汇来源 计算机科学 发明时间 1962

//节点最多的时候是满二叉树,如果认为第一层的高度为0,那么节点数最多应该是2^(h+1) -1

//把h理解成层数才是2^h-1,下面写的最多有错误

高度为 h 的 AVL 树,节点数 N 最多2^h − 1; 最少N(h)=N(h− 1) +N(h− 2) + 1。

最少节点数n 如以斐波那契数列可以用数学归纳法证明:

即:

N(0) = 1 (表示 AVL Tree 高度为0的节点总数)

N(1) = 2(表示 AVL Tree 高度为1的节点总数)

N(2) = 4(表示 AVL Tree 高度为2的节点总数)

N(h)=N(h− 1) +N(h− 2) + 1 (表示 AVL Tree 高度为h的节点总数)

节点的平衡因子是它的左子树的高度减去它的右子树的高度。带有平衡因子 1、0 或 -1 的节点被认为是平衡的。带有平衡因子 -2 或 2 的节点被认为是不平衡的,并需要重新平衡这个树。平衡因子可以直接存储在每个节点中,或从可能存储在节点中的子树高度计算出来。

AVL树造价信息

市场价 信息价 询价
材料名称 规格/型号 市场价
(除税)
工程建议价
(除税)
行情 品牌 单位 税率 供应商 报价日期
龙血 株高130cm,冠幅120-130cm 查看价格 查看价格

韶顺然花木场

13% 佛山市顺德区北滘镇韶顺然花木场
烟花 烟花;型号、规格:种类:烟花(塔形灌木); 规格:自然高×冠幅:120-150cm×80-100cm,土球直径:50cm;品牌:绿态;烟火 查看价格 查看价格

绿态

13% 深圳市宸洲环保科技有限公司
改性脂底涂 PCG351改性脂底涂 查看价格 查看价格

东方雨虹

kg 13% 深圳东方雨虹防水工程有限公司
附加层改性 PCG3005附加层改性 查看价格 查看价格

东方雨虹

kg 13% 深圳东方雨虹防水工程有限公司
胸径25-28cm,高度8.0-9.0m,冠幅4.0-5.0cm,容器苗 查看价格 查看价格

瀚艺

13% 南宁瀚艺生态苗圃种植基地
胸径30-35cm,高度10-11m,冠幅4.0-5.5m,容器苗 查看价格 查看价格

瀚艺

13% 南宁瀚艺生态苗圃种植基地
腊肠 胸径15-18cm,高度4.0-5.0m,冠幅2.5-3.0m,容器苗 查看价格 查看价格

瀚艺

13% 南宁瀚艺生态苗圃种植基地
胸径66-68cm,高度9-11m,冠幅4.5-6.0m 查看价格 查看价格

瀚艺

13% 南宁瀚艺生态苗圃种植基地
材料名称 规格/型号 除税
信息价
含税
信息价
行情 品牌 单位 税率 地区/时间
秋茄 苗高50-60cm 冠幅10—15cm 查看价格 查看价格

珠海市2022年9月信息价
秋茄 苗高100-110cm 冠幅15-40cm 查看价格 查看价格

珠海市2022年9月信息价
秋茄 苗高130-140cm 冠幅50-60cm 查看价格 查看价格

珠海市2022年9月信息价
秋茄 苗高160-170cm 冠幅50-100cm 查看价格 查看价格

珠海市2022年6月信息价
秋茄 苗高50-60cm 冠幅10—15cm 查看价格 查看价格

珠海市2022年3月信息价
秋茄 苗高100-110cm 冠幅15-40cm 查看价格 查看价格

珠海市2022年3月信息价
秋茄 苗高50-60cm 冠幅10—15cm 查看价格 查看价格

珠海市2021年12月信息价
秋茄 苗高130-140cm 冠幅50-60cm 查看价格 查看价格

珠海市2021年12月信息价
材料名称 规格/需求量 报价数 最新报价
(元)
供应商 报价地区 最新报价时间
豆青高0.4m 豆青 高0.4m|1株 1 查看价格 四川上千园林工程有限公司 四川   2020-12-15
、红绒 525棵安高30cm,25棵红绒(高×冠幅1200mm×1000mm)|1株 2 查看价格 梁氏苗圃杉苗基地 广东  湛江市 2015-11-16
造型 高2.6米,管5米|1株 2 查看价格 东莞市万好木业有限公司 全国   2020-07-02
胸径20(cm),高10(m)|8347株 1 查看价格 四川郫县永丰园艺场 四川  成都市 2015-08-19
丁香造型 丁香圆柱,高1.6米,圆柱周长60厘米|8个 1 查看价格 广东中建普联科技有限公司 广东   2021-02-26
荔枝、龙眼 胸径12cm,冠幅2m,高3m|50株 1 查看价格 中山市绿资园艺发展有限公司 广东  佛山市 2013-12-27
桂花 径10公分 高1.2m|1株 1 查看价格 四川上千园林工程有限公司 四川   2020-12-15
樟木 胸径50cm,冠幅9m,高8m|1株 1 查看价格 中山古镇杨发园林花木场 广东   2017-10-23

给出一个操作AVLTREE的完整程序 大部分由Peter Brass编写

AVL树本质上还是一棵二叉搜索树,它的特点是:

1.本身首先是一棵二叉搜索树。

2.带有平衡条件:每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1。

也就是说,AVL树,本质上是带了平衡功能的二叉查找树(二叉排序树,二叉搜索树)。

AVL树常见问题

旋转

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树插入可以通过如同它是未平衡的二叉查找树一样把给定的值插入树中,接着自底向上向根节点折回,于在插入期间成为不平衡的所有节点上进行旋转来完成。因为折回到根节点的路途上最多有 1.5 乘 log n 个节点,而每次 AVL 旋转都耗费恒定的时间,插入处理在整体上耗费 O(log n) 时间。 在平衡的的二叉排序树Balanced BST上插入一个新的数据元素e的递归算法可描述如下: 若BBST为空树,则插入一个数据元素为e的新结点作为BBST的根结点,树的深度增1; 若e的关键字和BBST的根结点的关键字相等,则不进行; 若e的关键字小于BBST的根结点的关键字,而且在BBST的左子树中不存在和e有相同关键字的结点,则将e插入在BBST的左子树上,并且当插入之后的左子树深度增加(+1)时,分别就下列不同情况处理之:BBST的根结点的平衡因子为-1(右子树的深度大于左子树的深度,则将根结点的平衡因子更改为0,BBST的深度不变; BBST的根结点的平衡因子为0(左、右子树的深度相等):则将根结点的平衡因子更改为1,BBST的深度增1; BBST的根结点的平衡因子为1(左子树的深度大于右子树的深度):则若BBST的左子树根结点的平衡因子为1:则需进行单向右旋平衡处理,并且在右旋处理之后,将根结点和其右子树根结点的平衡因子更改为0,树的深度不变; 若e的关键字大于BBST的根结点的关键字,而且在BBST的右子树中不存在和e有相同关键字的结点,则将e插入在BBST的右子树上,并且当插入之后的右子树深度增加(+1)时,分别就不同情况处理之。

删除

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

查找

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

AVL树文献

AVL燃油过滤器信息 AVL燃油过滤器信息

格式:pdf

大小:135KB

页数: 3页

评分: 4.4

Beijing Liaision Office A V L 李 斯 特 北 京 联 络 处 Suite 20A/B/F, Tower A, Gateway, No.18 Xiaguangli, North Road,East Third Ring, Chaoyang District, Beijing. People ’s Republic Of China. 100027 Tel: +86-10-5829 2800 Fax: +86-10-5829 2818 Hot Line: +86-10-65812970 北京市朝阳区东三环北路霞光里 18号佳城广场 A座 20A/B/F 单元邮编: 100027 电话: +86-10-5829 2800 传真: +86-10-5829 2818 热线: +86-10-65812970 Suzhou Huaye Testing Techn

立即下载
榉树、榆树、朴树的区别 榉树、榆树、朴树的区别

格式:pdf

大小:135KB

页数: 1页

评分: 4.4

俗称的红榉其实才是真正的榉树。 榔榆的俗名为白榉; 朴树的俗 名为青榉。 1.叶子不同,榆树的叶子两侧的锯齿是不规则的,而榉树一般 都是对称的。而且榆树叶子通常小而厚实, 而榉树叶子通常大而且较 为薄。榉树的叶子的边缘锯齿是特有的桃形锯齿, 而榆树就不是桃形 锯齿。朴树叶子从基部开始就分出三根叶脉, 很明显——榆树和榉树 都是一根主脉。 2.树皮不同,榆树皮灰色或暗灰色,幼龄树皮较平滑,老龄的 树皮粗糙,皮是纵向裂开的,所以比较粗糙,长条状纵裂。榉树树皮 灰色或红棕色;幼枝有白柔毛。榉树树皮通常不会开裂,即使是很老 的榉树的树皮脱落也是鳞片状的, 但树皮还是比较光滑的。 榉树的树 皮呈红棕色,而榆树的树皮呈暗灰色。朴树皮灰褐色,粗糙不开裂, 小枝密被柔毛。榉树脱的皮厚 ,榆树脱的皮很薄。

立即下载

概述

在计算机科学中,AVL树是最先发明的自平衡二叉查找树。AVL树得名于它的发明者 G.M. Adelson-Velsky 和 E.M. Landis,他们在 1962 年的论文《An algorithm for the organization of information》中发表了它。

节点计算

高度为 h 的 AVL 树,节点数 N 最多2^h − 1; 最少 (其中)。

最少节点数 n 如以斐波那契数列可以用数学归纳法证明:

Nh=F【h+ 2】 - 1 (F【h+ 2】是 Fibonacci polynomial 的第h+2个数)。

即:

N0 = 0 (表示 AVL Tree 高度为0的节点总数)

N1 = 1 (表示 AVL Tree 高度为1的节点总数)

N2 = 2 (表示 AVL Tree 高度为2的节点总数)

Nh=N【h− 1】 +N【h− 2】 + 1 (表示 AVL Tree 高度为h的节点总数)

换句话说,当节点数为 N 时,高度 h 最多为。

节点的平衡因子是它的右子树的高度减去它的左子树的高度。带有平衡因子 1、0 或 -1 的节点被认为是平衡的。带有平衡因子 -2 或 2 的节点被认为是不平衡的,并需要重新平衡这个树。平衡因子可以直接存储在每个节点中,或从可能存储在节点中的子树高度计算出来。

操作

AVL树的基本操作一般涉及运做同在不平衡的二叉查找树所运做的同样的算法。但是要进行预先或随后做一次或多次所谓的"AVL 旋转"。

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

单向右旋平衡处理RR:由于在*a的左子树根结点的左子树上插入结点,*a的平衡因子由1增至2,致使以*a为根的子树失去平衡,则需进行一次右旋转操作;

单向左旋平衡处理LL:由于在*a的右子树根结点的右子树上插入结点,*a的平衡因子由-1变为-2,致使以*a为根的子树失去平衡,则需进行一次左旋转操作;

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

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

插入

向AVL树插入可以通过如同它是未平衡的二叉查找树一样把给定的值插入树中,接着自底向上向根节点折回,于在插入期间成为不平衡的所有节点上进行旋转来完成。因为折回到根节点的路途上最多有 1.5 乘 log n 个节点,而每次 AVL 旋转都耗费恒定的时间,插入处理在整体上耗费 O(log n) 时间。 在平衡的的二叉排序树Balanced BST上插入一个新的数据元素e的递归算法可描述如下: 若BBST为空树,则插入一个数据元素为e的新结点作为BBST的根结点,树的深度增1; 若e的关键字和BBST的根结点的关键字相等,则不进行; 若e的关键字小于BBST的根结点的关键字,而且在BBST的左子树中不存在和e有相同关键字的结点,则将e插入在BBST的左子树上,并且当插入之后的左子树深度增加(+1)时,分别就下列不同情况处理之: BBST的根结点的平衡因子为-1(右子树的深度大于左子树的深度,则将根结点的平衡因子更改为0,BBST的深度不变; BBST的根结点的平衡因子为0(左、右子树的深度相等):则将根结点的平衡因子更改为1,BBST的深度增1; BBST的根结点的平衡因子为1(左子树的深度大于右子树的深度):则若BBST的左子树根结点的平衡因子为1:则需进行单向右旋平衡处理,并且在右旋处理之后,将根结点和其右子树根结点的平衡因子更改为0,树的深度不变; 若e的关键字大于BBST的根结点的关键字,而且在BBST的右子树中不存在和e有相同关键字的结点,则将e插入在BBST的右子树上,并且当插入之后的右子树深度增加(+1)时,分别就不同情况处理之。

删除

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

查找

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

参考实现

给出一个操作AVLTREE的完整程序 大部分由Peter Brass编写

代码实现

public class AVLTree<T extends Comparable<? super T>> {

private AVLNode<T> root;

public AVLTree() {root = null;}

/*** Check if given item x is in the tree.*/

public boolean contains(T x) {return contains(x, root);}

/*** Internal method to check if given item x is in the subtree.*

* @param x* the given item to check.

* @param t* the node that roots the subtree.*/

private boolean contains(T x, AVLNode<T> t) {while (t != null)

{int compareResult = x.compareTo(t.element);

if (compareResult < 0)

t = t.left;

else if (compareResult > 0)

t = t.right;

else

return true;}

return false;}

/*** Insert a new item to the AVL tree.*

* @param x

* the item to insert.*/

public void insert(T x) {

root = insert(x, root);}

/*** Internal method to insert into a subtree.*

* @param x

* the item to insert.

* @param t

* the node that roots the subtree.

* @return the new root of the subtree.*/

private AVLNode<T> insert(T x, AVLNode<T> t) {

if (t == null)

return new AVLNode<T>(x);

int compareResult = x.compareTo(t.element);

if (compareResult < 0)

{t.left = insert(x, t.left);

if (height(t.left) - height(t.right) == 2)

if (x.compareTo(t.left.element) < 0)

t = rotateWithLeftChild(t);

else

t = doubleWithLeftChild(t);}

else if (compareResult > 0)

{t.right = insert(x, t.right);

if (height(t.right) - height(t.left) == 2)

if (x.compareTo(t.right.element) > 0)

t = rotateWithRightChild(t);

else

t = doubleWithRightChild(t);}

else;

t.height = Math.max(height(t.left), height(t.right)) + 1;

return t;}

/*** Return the height of root t, or -1, if null.*

* @param t

* an AVLNode.

* @return the height.*/

private int height(AVLNode<T> t) {

return t == null ? -1 : t.height}

/*** Single rotation (left-left). Update height, then return new root.*/

private AVLNode<T> rotateWithLeftChild(AVLNode<T> z) {

AVLNode<T> y = z.left;

z.left = y.right;

y.right = z;

z.height = Math.max(height(z.left), height(z.right)) + 1;

y.height = Math.max(height(y.left), z.height) + 1;

return y;}

/*** Single rotation (right-right). Update height, then return new root.*/

private AVLNode<T> rotateWithRightChild(AVLNode<T> z) {

AVLNode<T> y = z.right;

z.right = y.left;

y.left = z;

z.height = Math.max(height(z.left), height(z.right)) + 1;

y.height = Math.max(height(y.right), z.height) + 1;

return y;}

/*** Double rotation (left-right).*/

private AVLNode<T> doubleWithLeftChild(AVLNode<T> z)

{z.left = rotateWithRightChild(z.left);

return rotateWithLeftChild(z);}

/*** Double rotation (right-left).*/

private AVLNode<T> doubleWithRightChild(AVLNode<T> z) {

z.right = rotateWithLeftChild(z.right);

return rotateWithRightChild(z);}

/**Remove item x.*/

public void remove(T x)

{root = remove(x, root);}

/*** Remove item x from subtree t.

* @param x the item to be removed.

* @param t the node that roots the subtree.

* @return the new root of the subtree.*/

private AVLNode<T> remove(T x, AVLNode<T> t) {

if (t == null)

return t;

int compareResult = x.compareTo(t.element);

if (compareResult < 0) {

t.left = remove(x, t.left);

if (height(t.right) - height(t.left) == 2)

if (height(t.right.left) < height(t.right.right))

t = rotateWithRightChild(t);

else

t = doubleWithRightChild(t);}

else if (compareResult > 0)

{t.right = remove(x, t.right);

if (height(t.left) - height(t.right) == 2)

if (height(t.left.left) > height(t.left.right))

t = rotateWithLeftChild(t);

else

t = doubleWithLeftChild(t);}

else if (t.left != null && t.right != null)

{t.element = findMin(t.right).element;

t.right = remove(t.element, t.right);

if (height(t.left) - height(t.right) == 2)

if (height(t.left.left) > height(t.left.right))

t = rotateWithLeftChild(t);

else

t = doubleWithLeftChild(t);}

else

{t = (t.left != null) ? t.left : t.right;}

if (t != null)

t.height = Math.max(height(t.left), height(t.right)) + 1;

return t;}

public T findMin()

{if (isEmpty())

return null;

return findMin(root).element;}

private AVLNode<T> findMin(AVLNode<T> t) {

while (t.left != null)

t = t.left;

return t;}

public T findMax()

{if (isEmpty())

return null;

return findMax(root).element;}

private AVLNode<T> findMax(AVLNode<T> t) {

while (t.right != null)

t = t.right;

return t;}

public void makeEmpty()

{root = null;}

public boolean isEmpty()

{return root == null;}

/** Internal class AVLNode */

private static class AVLNode<T>

{T element;

AVLNode<T> left;

AVLNode<T> right;

int height;

public AVLNode(T element)

{this(element, null, null);}

public AVLNode(T element, AVLNode<T> left, AVLNode<T> right)

{this.element = element;

this.left = left;

this.right = right;

this.height = 0;}}}

AVL

奥地利AVL公司和中国的友谊源远流长。公司创始人老李斯特教授在1926年到1932年的6年时间里,一直都在上海同济大学任教。 在过去的几十年里,公司创始人老李斯特教授及AVL公司始终把为中国培养一流的科技人材、支持中国发动机事业的独立快速发展放在第一位。

为此,他们向同济大学、吉林工业大学(现吉林大学)等科研教育单位捐赠了技术及设备;设立了奖学金,资助中国优秀学生,开展学术互访活动;为中国的汽车、火车、船用及工业用发动机进行开发设计、改型优化,并邀请中方技术人员参与相关的重要技术工作,在实践中培养中国发动机领域的人材,扶植中国发动机行业的独立发展。 老李斯特教授及AVL公司的倾心努力,得到了中国发动机行业的称赞。

奥地利的AVL公司联合设计开发了奇瑞 ACTECO系列发动机。

至今,中国的发动机行业一直把AVL公司亲切地称为"李斯特研究所",言意之中即认为AVL公司是一个科研开发、人材培训的理想基地。

AVL是世界三大权威内燃机研发机构之一。

AVL树相关推荐
  • 相关百科
  • 相关知识
  • 相关专栏