数据结构与算法分析(三) —— 关于树的深入探讨

前面介绍的链表结构的线性访问时间,在大规模输入数据时显得太慢了,因此,需要介绍一种新的数据结构,二叉查找树(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)。

你可能感兴趣的:(Java,数据结构与算法分析)