目录
树型结构是一类非常重要的非线性数据结构。树是以分支关系定义的层次结构。树结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构都可用树来形象表示。树在计算机领域中也得到广泛应用,如在编译程序中,可用树来表示源程序的语法结构。又如在数据库系统中,树形结构也是信息的重要组成形式之一。
一.树的定义
树(Tree)是n(n>=0)个结点的有限集。n=0时称为空树。n=0时称为空树。在任意一颗非空树中:
(1)有且仅有一个特定的称为根(Root)的结点,它只有直接后继,没有直接前驱;
(2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1,T2,......Tn,其中每一个集合本身又是一棵树并且称为根的子树(SubTree)。
1.树的相关概念
·节点的度:一个节点含有的子树的个数称为该节点的度;
·树的度:一棵树中,最大的节点的度称为树的度;
·叶节点或终端节点:度为零的节点;
·非终端节点或分支节点:度不为零的节点;
·父亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;
·孩子结点或子节点:一个节点含有的子树的根节点称为该节点的子节点;
·兄弟节点:具有相同父节点的节点互称为兄弟节点;
·节点的层次:从根开始定义,根为第一层,根的子节点为第二层,以此类推;
·深度:对于任意节点n,n的深度为从根到n的唯一路径长,根的深度为0;
·高度:对于任意节点n,n的高度为从n到一片树叶的最长路径,所有树叶的高度为0;
·堂兄弟节点:父节点在同一层的结点互为堂兄弟;
·节点的祖先:从根到该节点所经分支上的所有节点;
·子孙:以某节点为根的子树中任一节点都称为该节点的子孙;
·森林:由m(m>=0)棵互不相交的树的集合称为森林;
·树中任意节点的子节点之间没有顺序关系,这种树称为无序树,也称为自由树。反之是有序树。
对于树的定义还需要强调两点:
1.一课非空树中,根节点是唯一的,不可能存在多个根节点,数据结构中的树只能有一个根节点;
2.m>0时,子树的个数没有限制,但它们一定是不互相交的。
对比线性表与树的结构:
线性结构 | 树结构 |
第一个数据元素:无前驱 最后一个数据元素:无后继 中间元素:一个前驱一个后继 | 根节点:无双亲,唯一 叶节点:无孩子,可以多个 中间节点:一个双亲,多个孩子 |
二.二叉树的定义
2.1二叉树的定义
一颗二叉树是节点的一个有限集合,该集合或者为空,或者是由一个根节点加上两根分别称为左子树和右子树的,互不相交的,分别称为根节点的左子树和右子树的二叉树组成。二叉树是另一种树形结构,它的特点是每个结点至多只能有两颗子树(即二叉树不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能任意颠倒。
(a)空二叉树;(b)仅有根节点的二叉树;(c)右子树为空的二叉树;(d)左子树为空的二叉树;(e)左右子树均为非空的二叉树;
2.2特殊二叉树
2.2.1斜树
所有的结点都只有左子树的二叉树叫作左斜树。所有节点都是只有右子树的二叉树叫作右斜树。这两者统称为斜树。斜树有明显的特点,就是每一层都只有一个结点,结点的个数与二叉树的深度相同。
2.2.2满二叉树
在一棵二叉树中,如果所有分支节点都存在左子树和右子树,并且所有叶子都在同一层上,这样的二叉树称为满二叉树。(一颗深度为k且有2^(k-1)个结点的二叉树称为满二叉树)
单是每个结点都存在左右子树并不能满足二叉树,还必须要所有的叶子都在同一层上。
满二叉树的特点有:
(1)叶子只能出现在最下面一层。出现在其他层就不可能达到平衡;
(2)非叶子结点的度一定是2;
(3)在同样深度的二叉树中,满二叉树的结点最多,叶子个数最多。
2.2.3完全二叉树
对一棵具有n个结点的二叉树按层序编号,如果编号为i(1<=i<=n)的结点与同样深度的满二叉树中编号为i的结点在二叉树中的位置完全相同,则这棵二叉树称为完全二叉树
完全二叉树的特点:
(1)叶子结点只能出现最下两层;
(2)最下层的叶子一定集中在左部连续位置;
(3)倒数二层,若有叶子结点,一定都有右部连续位置;
(4)如果结点度为1,则该结点只有左孩子,即不存在只有右孩子的情况;
(5)同样结点树的二叉树,完全二叉树的深度最小。
三.二叉树的性质
性质1:在二叉树的第i层上至多有2^(i-1)个结点(i>=1);
性质2:深度为k的二叉树至多有2^k-1个结点(k>=1);
满二叉树是节点最多的二叉树,根据上图可以很直观的得出二叉树至多有2^k-1个结点。
性质3:对任何一棵二叉树T,如果其终端节点数为n0,度为2的结点树为n2,则n0=n2+1;
终端节点数其实就是叶子结点数,而一棵二叉树,除了叶子结点外,剩下的就是度为1或2的结点数了,我们设n1为度是1的结点数。则树T结点总数n=n0+n1+n2;
分支总线数=n-1=n1+2n2。又因为n=n0+n1+n2。所以n0=n2+1。
性质4:具有n个结点的完全二叉树的深度为[log2n]+1([x]表示不大于x的最大整数);
性质5:如果对一棵有n个结点的完全二叉树(其深度为[log2n]+1)的结点按层序编号(从第1层到第[log2n]+1层,每层从左到右),对任一节点i(1<=i<=n)有:
(1)如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲是结点[i/2]。
(2)如果2i>n,则结点i无左孩子(结点i为叶子结点);否则其左孩子是结点2i。
(3)如果2i+1>n,则结点i无右孩子;否则其右孩子是结点2i+1。
四.二叉树的存储结构
4.1二叉树的顺序存储结构
二叉树的顺序存储结构就是用一维数组存储二叉树中的结点,并且结点的存储位置,也就是数组的下标要体现结点之间的逻辑关系,比如双亲与孩子的关系,左右兄弟的关系等。
先来看看完全二叉树的顺序存储
由于它的严格定义,所以用顺序结构也可以表现出二叉树的结构来。对于一般的二叉树,可以将其按完全二叉树编号,只不过把不存在的结点设置为其他符号如"^"。
如果该二叉树为一棵右斜树,顺序存储就会浪费很多存储空间。
4.2二叉链表
因为顺序存储的适应性不强,所以我们在此研究一下链式存储结构。二叉树每个结点最多有两个孩子,所以为它设计一个数据域和两个指针域是比较自然的想法,我们称这样的链表叫作二叉链表。如果需要能快速找到双亲,则可以在增加一个指向双亲的指针域,这样就称为三叉链表。
leftchild | data | rightchild |
其中data是数据域,leftchild和rightchild都是指针域,分别存放左孩子和右孩子的指针。
参考资料:《大话数据结构 ——程杰》和《数据结构 ——严蔚敏》