1.36k likes | 1.43k Views
引入树. 线性表、堆栈和队列 都是线性结构,它们的共同特点:一对一; 计算机对弈 中的一个格局可能有多个后继格局,用线性结构难以描述。 树 是一种非线性结构,以分支关系定义层次结构,适宜描述一对多的嵌套性数据。. 第 9 章 树. 主要内容. 树和二叉树的基本概念 二叉树和树的存储结构 二叉树的抽象类 二叉树的遍历和树的遍历 二叉排序树 赫夫曼树及其应用. 9.1 树和二叉树的基本概念. 树的定义、术语及基本操作 二叉树的定义及其性质. 树的定义. 树是 n ( n>=0 )个结点的 有限集合 ; 如果 n=0 ,称为 空树 ;
E N D
引入树 • 线性表、堆栈和队列都是线性结构,它们的共同特点:一对一; • 计算机对弈中的一个格局可能有多个后继格局,用线性结构难以描述。 • 树是一种非线性结构,以分支关系定义层次结构,适宜描述一对多的嵌套性数据。
主要内容 • 树和二叉树的基本概念 • 二叉树和树的存储结构 • 二叉树的抽象类 • 二叉树的遍历和树的遍历 • 二叉排序树 • 赫夫曼树及其应用
9.1 树和二叉树的基本概念 • 树的定义、术语及基本操作 • 二叉树的定义及其性质
树的定义 • 树是n(n>=0)个结点的有限集合; • 如果n=0,称为空树; • 如果n>0,即在一棵非空树中: (1)有且仅有一个特定的结点称为根,它只有直接后继,但是没有直接前驱;
树的定义 (2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集合T1,T2,...,Tm,其中每一个集合本身又是一棵树,并且称之为根的子树。每棵子树的根结点有且仅有一个直接前驱,但可以有0个或多个直接后继。 • 可见,树的定义是一个递归的定义,即树的定义中又用到树的概念,此即树的固有特性。
J B H I A C D G F E 例:右面的图是一棵树 T T ={ A,B,C,D,E,F,G,H,I,J } A是根,其余结点可以划分为3个互不相交的集合: T1={ B,E,F } T2={ C,G } T3={ D,H,I,J } 这些集合中的每一集合都本身又是一棵树,它们是根 A的子树。 对于T1,B是根,其余结点可以划分为两个互不相交的集合: T11={ E } T12={ F } T11,T12是B的子树。
J B H I A C D G F E • 从逻辑结构看: 1)树中只有根结点没有前趋; 2)除根外,其余结点都有且仅一个前趋; 3)树的结点,可以有零个或多个后继; 4)除根外的其它结点,都存在唯一条从根到该结点的路径; 5)树是一种分支结构(除了一个称为根的结点外)每个元素都有且仅有一个直接前趋,有且仅有零个或多个直接后继。
C 文件夹1 文件夹n 文件1 文件2 文件夹21 文件夹22 文件21 文件22 • 树的应用 常用的数据组织形式——计算机的文件系统。 不论是DOS文件系统还是window文件系统,所有的文件都是用树的形式进行组织。
J B H I A C D G F E 树的术语 • 树的结点:包含一个数据元素的内容及若干指向子树的分支。 • 孩子结点:结点的子树的根称为该结点的孩子;如E是B的孩子。 • 双亲结点:B结点是A结点的孩子,则A结点是B结点的双亲;如B是E的双亲。 • 兄弟结点:同一双亲的孩子结点;如H、I、J互为兄弟。 • 堂兄结点:同一层上结点;如G与E、F、H、I、J互为堂兄。
J B H I A C D G F E 树的术语 • 祖先结点:某一结点的祖先是从根到该结点所经分支上的所有结点;如H的祖先为A、D。 • 子孙结点:以某结点为根的子树中的任一结点称为该结点的子孙;如A的子孙为B、C、D、E、F、G、H、I、J。 • 结点的度:结点子树的个数;如D的度为3。 • 叶子结点:也叫终端结点,是度为0的结点;如E、F、G、H、I、J。 • 分支结点:度不为0的结点;如A、B、C、D。
J B H I A C D G F E 树的术语 • 结点层次:根结点的层定义为0,根的孩子为第1层结点,依此类推。 • 树的高度(深度):树中结点的最大层次;如图所示树的高度为2。 • 树的度:树中各结点的度的最大值;如图所示树的度为3。
B C D E F G H I J K L M 树的术语 root 森林: F A 是 m(m≥0)棵互不相交的树的集合。 任何一棵非空树是一个二元组 Tree = (root,F) 其中:root 称为根结点,F 称为子树森林。 有序树:子树之间存在明确的次序关系的树。 无序树:不考虑子树的顺序。
树的基本操作 • 初始化:即置T为空树; • 求根结点:即求树T的根结点或是求结点x所在树的根结点; • 求双亲结点:求树T中结点x的双亲结点; • 求孩子结点:求树T中结点x的第i个孩子结点。
树的基本操作 • 求右兄弟:即求树T中结点x的右兄弟结点; • 建立一棵树:即生成一棵以x为根,以森林F为子树的一棵树; • 插入子树:即将以结点x为根的子树T'作为树T中结点y的第i棵子树。
树的基本操作 • 删除子树:即将以结点x为根的第i棵子树T‘从树T中删除; • 遍历:即按某个顺序依次访问树中的各个结点,并使每个结点只被访问一次; • 清除:即将树T置为空树。
线性结构VS 树型结构 根结点 (无前驱) 第一个数据元素 (无前驱) 多个叶子结点 (无后继) 最后一个数据元素 (无后继) 其他数据元素 (一个前驱、 多个后继) 其他数据元素 (一个前驱、 一个后继)
二叉树的定义 • 二叉树是一种普遍使用的树形结构; • 二叉树(Binary Tree)或为空树,或是由一个根结点及2棵不相交的左子树和右子树构成,并且左、右子树本身也是二叉树; • 二叉树的子树有左右之分,属于有序树。
二叉树的例子 右子树 根结点 A E B C F G D 左子树 H K 特点:1)每个结点的度≤2; 2)是有序树。
二叉树的五种基本形态: 只含根结点 空树 左右子树均不为空树 N 右子树为空树 左子树为空树 N N N L R L R
二叉树的性质1 : 若二叉树的层次从0开始,则第i层上至多有2i 个结点(i≥0)。 用归纳法证明: 1) i = 0层时,只有一个根结点: 2i = 20 = 1; 2) 假设对所有的 j,1≤ j i,命题成立; 3) 二叉树上每个结点至多有两棵子树,则第 i 层的结点数是i-1层的2倍,即2i-1 2 = 2i。
二叉树的性质2 : 高度为k的二叉树上至多含 2k+1-1个结点(k≥-1)。 证明: 基于上一条性质,深度为 k 的二叉树上的结点数至多为 20+21+ +2k = 2k+1-1。
二叉树的性质3 :对任何一棵二叉树,若它含有n0个叶子结点、n2 个度为2的结点,则必存在关系式:n0 = n2+1。 证明: 设,二叉树上结点总数 n = n0 + n1 + n2 又,二叉树上进入结点的分支总数b: b = n1+2n2(度为1的结点产生一条分支,度为2的结点产生两条分支) b = n-1(一个根结点的二叉树无分支,增加一个结点产生一条分支) b= n0 + n1 + n2 - 1 由此, n0 = n2 + 1 。
两种特殊的二叉树 • 满二叉树(Full Binary Tree)如果高度为k的二叉树,有2k+1-1个结点,则称为满二叉树;或者说在二叉树中每层的结点数达到最大。 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
两种特殊的二叉树 • 完全二叉树(Complete Binary Tree)1、树中所含的n 个结点和满二叉树中编号为 1 至 n 的结点一一对应; 2、一棵二叉树,只有最下一层结点数未达到最大,且最下层结点都集中在该层的最左端。 a a b c c b d e f g d e j h i
完全二叉树的特点是: • 叶子结点只可能在层次最大的两层上出现; • 对任何一个结点,若其右子树的高度为h,则其左子树的高度只能是h或h+1。
二叉树的性质4 :具有 n 个结点的完全二叉树的高度为: log2(n+1)-1。 证明: 设完全二叉树的高度为k ,结点数为n, 则据第二条性质得2k-1< n ≤ 2k+1-1 2k <n +1≤2k+1 k <log2 (n+1) ≤ k+1 因为 k 只能是整数, k =log2(n+1)- 1 。
二叉树的性质5 若对含 n 个结点的完全二叉树从上到下、从左至右进行 0至 n的编号,则对完全二叉树中任意一个编号为 i的结点:(1) 若i=0,则该结点是二叉树的根,无双亲, 否则,编号为(i-1)/2的结点为其双亲结点。(2) 若 2i+1>n,则该结点无左孩子;若2i+1≤n,编号为2i+1的结点为其左孩子结点。(3) 若 2i+2>n,则该结点无右孩子; 若2i+2≤n,编号为2i+2的结点为其右孩子结点。
性质5举例 • 若 i=0,该结点是二叉树的根, 无双亲; 若 i≠0,编号为(i-1)/2 的结点为其双亲。 • 若2i+1>n,该结点无左孩子 (i=6,7); 若2i+1≤n,编号为2i+1 的 结点为其左孩子(i=4,5)。 • 若 2i+2>n,该结点无右孩子(i= 5,6,7); 若2i+2≤n,编号为2i+2 的结点为其右孩子(i=2,3)。 0 1 2 3 4 5 6 7 8 9
小 结 • 树的定义 • 树的有关术语 • 树的基本操作 • 二叉树的定义 • 二叉树的性质
9.2 二叉树的存储结构 • 顺序存储结构:数组表示 • 链式存储结构:二叉链表 三叉链表
0 F A E D C B 0 1 2 3 4 5 6 1 2 A B C D E F 3 4 5 二叉树的顺序存储 对于完全二叉树,采用一组连续的内存单元,按编号顺序依次存储完全二叉树的结点。
0 1 2 3 4 5 6 B C D C B A A E D E G G F F 9 7 8 二叉树的顺序存储 对于一棵一般的二叉树,如果补齐构成完全二叉树所缺少的那些结点,便可以对二叉树的结点进行编号。
0 1 2 3 4 5 6 C E D A B G F 9 7 8 0 1 2 3 4 5 6 7 8 9 A B C D E 0F 0 0 G 二叉树的顺序存储 将二叉树原有的结点按编号存储到内存单元“相应”的位置上。
顺序存储结构的缺点 一般的二叉树会比完全二叉树少很多结点,造成空间浪费,例如单支树就是一个极端情况。
二叉树的链式存储 1、二叉链表 2、三叉链表
lchild data rchild 1. 二叉链表 Parent A D Data B E C LChild RChild F 结点结构:
二叉链表图示 root A D B A E C B D F C E F
lchild data rchild 二叉链表的结点 结点结构: struct BintreeNode{ //结点结构 Type data; //结点的数据域 BintreeNode * Lchild; //左孩子指针 BintreeNode * Rchild; //右孩子指针 }; 在建立其抽象类时,整个二叉树链表需要一个表头指针,它指向二叉树的根结点。
parent lchilddata rchild 2.三叉链表 结点结构: root A D B C E F
parent lchilddatarchild 三叉链表的结点 结点结构: struct BintreeNode{ Type data; //结点的数据域 BintreeNode * Lchild; //左孩子指针 BintreeNode * Rchild; //右孩子指针 BintreeNode * Parent ; //双亲结点指针 };
小 结 • 顺序存储结构:数组表示 • 链式存储结构:二叉链表 三叉链表
9.3 树的存储结构与转换 • 树的存储结构 • 树、森林与二叉树的转换
树的存储结构 • 顺序存储结构:双亲表示法 • 孩子(双亲)表示法:(顺序+链式) • 孩子-兄弟表示法:链式
双亲表示法 • 假设以一组连续空间存储树的各结点,每个结点又设有两个域,结点类型如下: struct TreeNode{ Type data; //结点的数据域 TreeNode *Parent; //结点双亲指针 }; data域记录数据信息,Parent为指针,它指向其双亲结点。 data parent 结点结构:
树的双亲表示法 data parent A 数组下标 0A-1 1B0 2C0 3D0 4E1 5F2 6 G2 7 H 2 B D C E F G H 双亲结点在数组中的位置,-1表示无双亲 特点: 找双亲方便,找孩子难
树的链式存储 通过保存树中每个结点的孩子结点的位置,表示树中结点之间的结构关系。 • 多重链表 • 单链表
多重链表(类似于二叉链表) • 两种方式:定长结点 和 不定长结点 定长结点:优点是结点结构一致,便于实现树的操作。缺点是浪费一些内存空间。 不定长结点:优点是节省内存空间。缺点是不定长的结点会使一些操作实现变复杂。
单链表表示法 线性表 +单链表 • 将每个结点的孩子结点排列起来,构成一个单链表,称为孩子链表; • n个结点共有n个孩子链表(叶子结点的孩子链表为空表); • n个结点的孩子链表头指针又组成一个顺序表。
孩子链表表示法 此时,单链表中各结点由两个域构成:struct TreeNode{ // 结点定义 Type data; TreeNode *next }; TreeNode *vertex[n]; //顺序表是一个指针数组,数组元素是指向孩子链表的头指针,n个结点n个指针。