数据结构与算法分析(三) —— 关于树的深入探讨
来源:互联网 发布:破解手机收费软件 编辑:程序博客网 时间:2024/06/06 01:24
前面介绍的链表结构的线性访问时间,在大规模输入数据时显得太慢了,因此,需要介绍一种新的数据结构,二叉查找树(BST)。
我们先对BST及其引申树的因果关系作介绍,再分别进行详细介绍,最后进行一些比较。
BST可以实现对数平均开销,但这严重依赖于输入,即要求输入是随机的,如果输入是有序数据,由于BST失衡,导致线性平均开销。
因此,需要对BST进行改造,引入平衡的结构条件。平衡二叉树的常用算法很多,形成的树结构有红黑树、AVL树、B-/B+树、伸展树等。
AVL树是通过附加一个平衡条件(每个节点的左子树和右子树的高度最多差1)来改造的,所以它也被称为高度平衡树。
AVL树可以保证最坏情形下对数时间的时间界。
伸展树是通过自调整类结构来改造的。伸展树的各种操作的摊还时间为对数时间。
1、树
(1)树的定义一般采用递归的方式。
实现树的常用方法是将每个节点的所有儿子都放在树结点的链表中。
树的应用很多,流行的用法之一是包括UNIX和DOS在内的许多常用操作系统中的目录结构。
(2)在具体一点的二叉树,有个很重要的性质就是其平均深度为0(sqrt(N))。
二叉树的主要用处之一是在编译器的设计领域。
(3)上面说的应用实际上具体为表达式树,这里要了解先序遍历(右、左、节点),中序遍历(左、节点、右)和后序遍历(左、右、节点)。
(4)二叉树的另一个主要应用即在查找中的使用,即后面我们要详述的二叉查找树。
2、BST
(1)定义
- 若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 左、右子树也分别为二叉排序树;
- 没有键值相等的结点。
(2) 操作效率
查找最好时间复杂度O(logN),最坏时间复杂度O(N)。
插入删除操作算法简单,时间复杂度与查找差不多。
(3)插入和删除操作容易导致BST失衡,进一步引入后面的平衡二叉树。
(4)实现
详见博文BST的Java实现
3、AVL树
(1)定义
- 本身首先是一棵二叉搜索树
- 它的左子树和右子树都是AVL树
- 左子树和右子树的高度差不能超过1
(2)操作效率
- 查找 : AVL不会出现最差情况的BST(单支树),因此查找在平均和最坏情况下都是O(log n)
- 插入 : AVL的每一次插入结点操作最多只需要旋转1次(单旋转或双旋转),因此总体上插入操作的代价仍然在O(logN)级别上(插入结点需要首先查找插入的位置)
- 删除 : 每一次删除操作最多需要O(logN)次旋转,因此,删除操作的时间复杂度为O(logN)+O(logN)=O(2logN)
(3)一些性质
- 一棵N个结点的AVL树的其高度保持在0(log(N)),不会超过3/2log(N+1)
- 一棵N个结点的AVL树的平均搜索长度保持在0(log(N))
- 在高度为h的AVL树中,最少节点数S(h)=S(h-1)+S(h-2)+1,其中S(0)=1,S(1)=2
(4)详见博文AVL的java实现
4、伸展树
(1)放弃附加平衡条件,允许树有任意的深度,但每次操作(一个节点被访问)之后都要使用一个调整规则(此节点经一系列AVL树的旋转被推到根上)来进行调整,是的后续操作高效。
(2)与带平衡结构的树相比较,优点在于:
- 由于它们可以根据具体使用情况进行调整,所以在使用模式不均匀的情况下更加有效
- 由于无需存储平衡信息或者其它限制信息,所以所需的存储空间更小
- 它们的查找和更新算法概念和操作都很简单,易于实现
缺点在于:
- 需要更多的局部调整,尤其是在查找期间。而那些有明确限制的数据结构仅需要在更新期间进行调整,查找期间则不用
- 一系列查找操作中的某一个可能会耗时较长,这在实时应用程序中可能是一个不足之处
(3)各种基本操作的摊还时间复杂度为0(log(n))
5、B树
(1)B-tree,是一种平衡的多叉树,称为B树(或B-树、B_树)。
阶为M的B-树的定义:
- 根结点至少有两个儿子
- 每个非根节点所包含的关键字个数 j 满足:┌M/2┐ - 1 <= i <= m - 1
- 除根结点以外的所有结点(不包括叶子结点)的度数正好是关键字总数加1,故内部子树个数 k 满足:┌M/2┐ <= k <= M
- 所有的叶子结点都位于同一层
(2)B+树是应文件系统所需而出的一种B-树的变型树。
M阶的B+树定义为:
- 数据项存储在树叶上
- 非叶节点存储直到M-1个关键字以指示搜索的方向,关键字i代表子树i+1中的最小的关键字
- 树的根或者是一片树叶,或者其儿子数在2和M之间
- 除根外,所有非树叶节点的儿子数k满足┌M/2┐ <= k <= M
- 所有的树叶都是在相同的深度上,并有┌L/2┐和L之间个数据项,其中L的确定应用时的所存储的项大小来选择
(3)B树用处
当数据量大的术后,无法放入驻村,这时就需要从磁盘进行读写了。而一次磁盘的访问价值大约是40万条指令,由于磁盘访问代价太高,因此,可以用大量的计算来节省一次磁盘访问。
为了大幅降低磁盘访问次数,可以将BST增加分支减小高度,即B树的理论雏形。亦可完全二叉树的高度约为log2(N),而一颗完全M叉树的高度约为logM(N)。
- 数据结构与算法分析(三) —— 关于树的深入探讨
- 数据结构与算法分析(二) —— 关于表、栈和队列的深入探讨
- 数据结构与算法分析(一) —— 深入理解递归算法的调用过程
- 数据结构与算法分析(三) —— 二叉查找树的实现
- 数据结构与算法分析(三) —— AVL树的实现
- 关于shared pool的深入探讨(三)
- 关于sharedpool的深入探讨(三)
- 基于 Python 的数据结构与算法分析学习记录(6-6)—— 分析树
- 《数据结构与算法分析c++描述》读书笔记三——AVL树
- 数据结构——关于KMP算法的效率分析
- 关于RTX51 TINY的分析与探讨
- 数据结构与算法(三)--二叉树
- 【算法】数据结构与算法分析学习笔记——各类二叉查找树的吐血整理
- 数据结构与算法的分析
- 数据结构与算法(12)——栈习题三
- 学习JavaScript数据结构与算法(三)——队列
- 数据结构与算法分析——最大公约数
- 数据结构与算法分析——单链表
- HDU 3466 Proud Merchants
- section 1.5 numtri
- 5-15 计算圆周率 (15分)
- HTML标记语言介绍
- MYSQL 相关
- 数据结构与算法分析(三) —— 关于树的深入探讨
- hdu 3658 HDU 3658 How many words(矩阵快速幂)
- 【数字图像处理学习笔记之五】形态学开闭运算
- adb 命令
- Android Studio 问题解决记录
- linux学习日记(二)
- Treap学习小计
- Java NIO 学习(三)--FileChannel
- 5、最长公共子序列