第6章 树状结构

  • 前言
  • 6.1 树
  • 6.2 二叉树简介
  • 6.2.1二叉树的定义
  • 6.2.2特殊二叉树简介
  • 6.3 二叉树存储方式
  • 6.3.1数组表示法
  • 6.3.2列表表示法
  • 6.4 二叉树的遍历
  • 6.4.1中序遍历
  • 6.4.2前序遍历
  • 6.4.3后序遍历
  • 6.4.4二叉树的遍历实现
  • 6.4.5二叉运算树
  • 6.5二叉树的高级研究
  • 6.5.1二叉排序树
  • 6.5.2二叉搜索树
  • 6.5.3线索二叉树
  • 6.6 数的二叉树表示法
  • 6.6.1树转换为二叉树
  • 6.6.2树林转换为二叉树
  • 6.6.3树与树林的遍历
  • 6.6.4确定唯一二叉树
  • 小结


前言

       数(tree)是另外一种典型的数据结构,可用来描述有分支的结构,属于一种阶层性的非线性结构。从企业的组织架构、家族内的族谱,再到计算机领域中的操作系统与数据库管理系统都是树状结构的衍生运用。

6.1 树



树状结构 mysql 树状结构表将mesh_子树


6.2 二叉树简介

       一般树状结构在计算机内存中的存储方式以链表为主。对于n元树来说,因为每个节点的分支都不相同,所以为了方便起见,我们必须取n为链接个数的最大固定长度,而每个节点的数据结构如下:



树状结构 mysql 树状结构表将mesh_Java_02


       需要注意,这种n元树十分浪费链接空间。当n=2时,它的链接浪费率最低,所以为了改进内存空间浪费的缺点,我们最常使用二叉树结构来取代树状结构。

6.2.1二叉树的定义



树状结构 mysql 树状结构表将mesh_树状结构 mysql_03


6.2.2特殊二叉树简介

  • 满二叉树


树状结构 mysql 树状结构表将mesh_树状结构 mysql_04


  • 完全二叉树


树状结构 mysql 树状结构表将mesh_树状结构 mysql_05


  • 歪二叉树


树状结构 mysql 树状结构表将mesh_二叉树_06


  • 严格二叉树


树状结构 mysql 树状结构表将mesh_数据结构与算法_07


6.3 二叉树存储方式

       树状结构在程序中的建立与应用大多使用链表来处理,因为链表的指针用来处理树相当方便,只需改变指针即可。此外,也可以使用数组这样的连续内存来表示二叉树。至于使用数组或链表都各有利弊。

6.3.1数组表示法



树状结构 mysql 树状结构表将mesh_二叉树_08



树状结构 mysql 树状结构表将mesh_数据结构与算法_09


6.3.2列表表示法

6.4 二叉树的遍历

       二叉树的遍历,最简单的说法就是“访问树中所有的节点各一次”,并且在遍历后,将树中的数据转化为线性关系。其实二叉树的遍历,并不像之前所提到的线性数据结构般简单,就以一个简单的二叉树节点而言,每个节点都可分为左右两个分支,所以一共可以有ABC、ACB、BAC、BCA、CAB、CBA 6种遍历方法。如果是按照二叉树特性,一律由左向右,就只剩下三种遍历方式,分别是BAC、ABC、BCA。



树状结构 mysql 树状结构表将mesh_Java_10


这三种遍历方式的命名与规则:

中序遍历(BAC):左子树→树根→右子树
前序遍历(ABC):树根→左子树→右子树
后序遍历(BCA):左子树→右子树→树根

6.4.1中序遍历

6.4.2前序遍历

6.4.3后序遍历

6.4.4二叉树的遍历实现

6.4.5二叉运算树

6.5二叉树的高级研究

       除了前面学习的二叉树遍历方式外,二叉树还有许多常见的应用,例如二叉排序树、二叉搜索树、线索二叉树。

6.5.1二叉排序树

6.5.2二叉搜索树

6.5.3线索二叉树



树状结构 mysql 树状结构表将mesh_树状结构 mysql_11


6.6 数的二叉树表示法

       二叉树只是树状结构的特例,广义的树状结构其父节点可以拥有多个子节点,称这样的树为多叉树。由于二叉树的链接浪费率最低,因此可把树转换成二叉树来操作,可以增加许多操作上的便利。

6.6.1树转换为二叉树

6.6.2树林转换为二叉树

6.6.3树与树林的遍历

6.6.4确定唯一二叉树

小结

  • 树(tree)是由一个或一个以上的节点所组成的有限集合,具有树根(root),其余的节点分为n>=0个互斥的集合,T1,T,2,T3… …Tn,且每个集合称为子树。
  • 每一个节点的上层节点为父节点,没有父节点的节点为根节点。
  • 子树的个数为该节点的度,没有子节点的节点,即度为0。
  • 树林是n个互斥树的集合(n>=0),移去树根即为树林。
  • 所谓祖先,是指从树根到该节点路径上所包含的节点,儿子孙则是在该节点子树中的任一节点。
  • 二叉树(又称knuth树)是一个由有限节点所组成的集合,此集合可以为空集合,或由一个树根及左右两个子树所组成。
  • 如果二叉树的高度为h,树的节点数为2^h-1,h>=0,则我们称此数为“满二叉树”(full binary tree)。
  • 如果二叉树的深度为h,所含的节点数小于2^h-1,但其节点的编号方式如同深度为h的满二叉树一样,从左到右,由上到下的顺序一一对应。
  • 当一个二叉树完全没有右节点或左节点时,我们就把它称为左歪斜树或右歪斜树。
  • 二叉树的每个非终端节点均有非空的左右子树。
  • 二叉树的存储方式可以使用数组或链表
  • 以数组表示法来存储二叉树,如果越接近满二叉树,则越省空间,如果是歪斜树则最浪费空间。
  • 使用链表来表示二叉树的好处是对于节点的增加与删除相当容易,缺点是很难找到父节点。
  • 二叉树的遍历(Binary Tree Traversal),最简单的说法就是“访问树中所有的节点各一次”,并且在遍历后,将树中的数据转化为线性关系。
  • 中序遍历的顺序为:左子树→右子树→树根。
  • 如果一个二叉树符合“每一个节点的设局大于左子节点且小于右子节点”,这棵树便称为二分树。因为二分树便于排序及搜索,二叉排序树或二叉搜索树都是二分树的一种。
  • 使用链表建立的n节点二叉树,实际上用来指向左右两节点的指针只有n-1个链接,另外的n+1个指针都是空链接。所谓“线索二叉树”(Threaded Binary Tree)就是把这些空的链接加以利用,再指到数的其他节点,而这些链接就称为“线索”(thread)。
  • 在二叉树的三种遍历方法中,如果有中序与前序的遍历结果或者中序与后序的遍历结果,可由这些结果求得唯一的二叉树。不过如果只具备前序与后序的遍历结果就无法确定唯一二叉树。