- 1、本文档共14页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
java数据结构与算法之平衡二叉树 (AVL树)的设计与实现
普通二叉查找树的问题
在开篇,我们提到过,普通二叉树(二叉查找树)在操作的时间复杂度上不一定遵循 0(吨 n),也有可能是0(n),这是为什么呢?在上一篇中, 我们明明插入都按照一定规则比较的呀, 其实那是因为我们在上篇测试时执行了随机插入的操作, 如果此时利用上篇实现的二叉搜索
树将一段已排序好的数据一个个插入后,就会发现如下情况了:
从图中我们可以发现,把已排序的 1-9数据进行正序和倒序插入后,树的结构已变成单向
左子树或者右子树了, 如果我们在往里插入已排序的数据, 那么单向左子树或者右子树越来
越长,此时已跟单链表没有什么区别了,因此对此结构的操作时间复杂度自然就由 0(吨n)
变成0(n) 了,这也就是普通二叉查找树不是严格意义上 0(吨n)的原因。那么该如何解决这
个问题呢?事实上一种解决的办法就是要有一个称为平衡的附加结构条件即: 任何结点的深
度不得过深,而这种数据结构就是我们本篇要分析的平衡二叉树( AVL ),它本身也是一种
二叉查找树,只不过不会出现前面我们分析的情形罢了, 接下来我们就来分析一下这棵平衡
二叉树。
平衡二叉树的定义
通过上面的分析,我们明白的普通二叉查找树的不足, 也知道了如何去解决这个缺点, 即
构建树时要求任何结点的深度不得过深(子树高度相差不超过 1),而最终这棵树就是平衡
二叉树(Bala need Bin ary Tree),它是 G.M. Adelso n-Velsky 和 E.M. La ndis 在 1962 年在论文 中发表的,因此又叫 AVL树。这里我们还需要明确一个概念, AVL树只是实现平衡二叉树
的一种方法,它还有很多的其他实现方法如红黑树、替罪羊树、 Treap、伸展树等,后面我
们还会分析其他树的实现。 ok~,接着来了解一下 AVL树的特性:一棵 AVL树是其每个结
点的左子树和右子树的高度最多相差 1的二叉查找树(空树的高度为-1),这个差值也称为平
衡因子(其取值可以是 1, 0, -1,平衡因子是某个结点左右子树层数的差值,有的书上定
义是左边减去右边, 有的书上定义是右边减去左边, 这样可能会有正负的区别, 但是这个并
不影响我们对平衡二叉树的讨论)。如下图
川4■塾二囂卿|*人卄1
川4■塾二囂卿|*人卄
1 卸-■甲• A
图(1)显然就是一棵平衡二叉树, 它每个结点的左子树和右子树的高度最多相差 1,同时也是
一棵二叉查找树,而图二虽然也是一棵二叉查找树, 但是它每个结点的左子树和右子树的高
度相差却到达了 2,因此不是平衡二叉树。理解了平衡二叉树的概念后,我们在思考一下, 那些操作可能引起平衡发生变化呢?显然只有那些引起结点数量变化的操作才可能导致平
衡被改变,也就是删除和插入操作了,如下图,我们把 6插入到图a后,结构变成了图b,
这时原本的平衡二叉树就失去平衡了。
显然图b已失去平衡,如果发生这样的情况,我们就必须考虑插入元素后恢复二叉树的平衡 性质,实际上也总是可以通过对树进行简单的修复来让其重新恢复到平衡, 而这样的简单操
作我们就称之为旋转, 当然旋转也有单旋转和双旋转之分, 下面我们将会 分析, 这里有
点需要明白的是,无论是插入还是删除,只有那些从插入或者删除点到根结点的路径上的结 点的平衡才有可能被改变, 因为只有这些结点的子树才可能发生变化, 所以最终也只需针对
这些点进行平衡修复操作即可。
平衡二叉树的设计与实现
ok~,有了旋转的概念后,我们接着了解如何通过旋转来修复一棵失衡的二叉树,这里假
设结点X是失衡点,它必须重新恢复平衡,由于任意结点的孩子结点最多有两个,而且导
致失衡的必要条件是 X结点的两棵子树高度差为 2(大于1),因此一般只有以下 4种情况可 能导致X点失去平衡:
在结点X的左孩子结点的左子树中插入元素
在结点X的左孩子结点的右子树中插入元素
在结点X的右孩子结点的左子树中插入元素
在结点X的右孩子结点的右子树中插入元素
以上4种情况,其中第①情况和第④情况是对称的, 可以通过单旋转来解决,而第②种情况 和第③情况是对称的,需要双旋转来解决。在分析这四种情况前,我们先看看 AVL的结点
该如何设计的,其声明如下:
package com.zejian.structures.Tree.AVLTree;
* Created by zejian on 2016/12/25.
* Blog : /javazejian [ 原文地址 ,请尊重原创 ]
* 平衡二叉搜索树 (AVL 树 )节点
*/
public class AVLNodeT extends Comparable {
public A VLNodeT left;// 左结点
文档评论(0)