1.22k likes | 1.38k Views
第六章 树和二叉树. 数据结构. 树的定义和基本术语. 6.1. 二叉树. 6.2. 遍历二叉树和线索二叉树. 6.3. 树和森林. 赫夫曼树及其应用. 6.4. 6.6. 内容提要. 基本 要求. 重点. 难点. 基本要求、重点、难点. ( 1 )掌握树结构的定义、特点、基本术语和基本操作。 ( 2 )掌握二叉树的定义、操作、性质及存储结构特点。 ( 3 )掌握二叉树遍历的递归算法和非递归算法。 ( 4 )掌握树的存储结构、树与二叉树的转换和森林与二叉树的转换。 ( 5 )掌握二叉排序树和哈夫曼树以及应用.
E N D
第六章 树和二叉树 数据结构
树的定义和基本术语 6.1 二叉树 6.2 遍历二叉树和线索二叉树 6.3 树和森林 赫夫曼树及其应用 6.4 6.6 内容提要
基本 要求 重点 难点 基本要求、重点、难点 (1)掌握树结构的定义、特点、基本术语和基本操作。 (2)掌握二叉树的定义、操作、性质及存储结构特点。 (3)掌握二叉树遍历的递归算法和非递归算法。 (4)掌握树的存储结构、树与二叉树的转换和森林与二叉树的转换。 (5)掌握二叉排序树和哈夫曼树以及应用 二叉树的各种存储结构的特点及适用范围,按各种次序遍历二叉树的递归和非递归算法,二叉树的线索化,树的各种存储结构及其特点,编写树的各种运算的算法,建立最优二叉树和哈夫曼编码的方法。 二叉树的性质,建立最优二叉树和哈夫曼编码的方法。
A C B H G F E D J I 6.1 树的类型定义 一、 树的定义 1.树的定义 树(Tree)是n(n≥0)个有限数据元素的集合。在任意一棵非空树T中: 123 4 (1)有且仅有一个特定的称为树根(Root)的结点,根结点无前趋结点; (2)当n>1时,除根结点之外的其余结点被分成m(m>0)个互不相交的集合T1,T2,…,Tm,其中每一个集合Ti(1≤ i ≤m)本身又是一棵树,并且称为根的子树。
A B C D E F G H I J K L M 例如 A 只有根结点的树 有13个结点的树 其中:A是根;其余结点分成三个互不相交的子集, T1={B,E,F,K,L}; T2={C,G}; T3={D,H,I,J,M}, T1,T2,T3都是根A的子树,且本身也是一棵树
A C B H D E G F I J 2.树的其它表示法 (1)嵌套集合法 嵌套集合法,也称为文氏图法(Venn Diagram),它是用集合以及集合的包含关系来描述树形结构,每个圆圈表示一个集合,套起来的圆圈表示包含关系。
A B D E J F C G H ( 2 ) 圆括号表示法 圆括号表示法也称为广义表表示法,它是使用括号将集合层次与包含关系显示出来。 ( A ( B ( D, E ( I, J ), F ), C ( G, H ) ) ) ( 3 ) 凹入法 凹入法是用不同宽度的行来显示各结点,而行的凹入程度体现了各结点集合的包含关系,。 树的凹入表示法主要用于树的屏幕显示和打印输出。 I
3 .基本术语 (1)结点——树的结点包含一个数据及若干指向其子树的分支。 (2)结点的度——结点所拥有的子树数称为该结点的度(Degree)。 (3)树的度——树中各结点度的最大值称为该树的度。 (4)叶子(终端结点)——度为零的结点称为叶子结点。 (5)分枝结点——度不为零的结点称为分支结点。 (6)兄弟结点——同一父亲结点下的子结点称为兄弟结点。 (7)层数——树的根结点的层数为1,其余结点的层数等于它双亲结点的层数加1。 (8)树的深度——树中结点的最大层数称为树的深度(或高度)。 (9)有向树: 有确定的根; 树根和子树根之间为有向关系。
1层 A 2层 B C D height = 4 3层 E F G H I J 4层 K L M 例如:
大家来思考 问题 ??? 回答: n1+n2+…+nM+n0+=1+n1+2n2+…+mnM =>n0+=1+n2+…+(m-1)nM 问题: 已知一棵树为m的树中有n1个度为1的结点,n2个度为2的结点,…nm个度为m的结点,问该树中有多少片叶子
练习一下吧 1.设树T的度为4,其中度为1,2,3和4的结点个数分别为4,2,1,1 则T中的叶子数为( ) A.5 B.6 C.7 D.8 2.如果结点A有 3个兄弟,而且B是A的双亲,则B的度是______。
A B D C B C D H G I J E F K J I K F G H E (10)森林——零棵或有限棵互不相交的树的集合称为森林。 在数据结构中,树和森林并不象自然界里有一个明显的量的差别。任何一棵树,只要删去根结点就成了森林。 (a) 树 (b) 移去根结点后成为森林 (11)有序树和无序树——树中结点的各子树从左到右是有次序的(即不能互换位置),称这样的树为有序树;否则称为无序树。
4.树的抽象数据类型定义 ADT Tree{ 数据对象D: 数据关系R: 基本操作 P: } ADT Tree D是具有相同特性的数据元素的集合。 若D为空集,则称为空树;//允许n=0 若D中仅含一个数据元素,则R为空集; 其他情况下的R存在二元关系: ① root 唯一 //关于根的说明 ② Dj∩Dk= Φ //关于子树不相交的说明 ③ …… //关于数据元素的说明 //至少有15个,如求树深,求某结点的双亲
基本操作 P: Root(T) // 求树的根结点 Value(T, cur_e) // 求当前结点的元素值 Value(T, cur_e) // 求当前结点的元素值 Parent(T, cur_e) // 求当前结点的双亲结点 RightSibling(T, cur_e) // 求当前结点的右兄弟 LeftChild(T, cur_e) // 求当前结点的最左孩子 TreeEmpty(T) // 判定树是否为空树 TreeDepth(T) // 求树的深度 TraverseTree( T, Visit() ) // 遍历 InitTree(&T) // 初始化置空树 CreateTree(&T, definition) // 按定义构造树 InsertChild(&T, &p, i, c) // 将以c为根的树插入为结点p的第i棵子树 Assign(T, cur_e, value) // 给当前结点赋值 ClearTree(&T) // 将树清空 DestroyTree(&T) // 销毁树的结构 DeleteChild(&T, &p, i) // 删除结点p的第i棵子树
想一想: . 树型结构与线性结构的结构特点比较? 树型结构 根结点(无前驱) 多个叶子结点(无后继) 其它数据元素(一个前驱、多个后继) 线性结构 第一个数据元素(无前驱) 最后一个数据元素(无后继) 其它数据元素(一个前驱、一个后继)
6.2 二叉树的类型定义 • 为何要重点研究每结点最多只有两个 “叉” 的树? • 二叉树的结构最简单,规律性最强; • 可以证明,所有树都能转为唯一对应的二叉树,不失一般性。 6.2.1 二叉树的定义 6.2.2 二叉树的性质 6.2.3 二叉树的存储结构
6.2 二叉树的类型定义 6.2.1 二叉树的定义 1、定义: 二叉树或为空树,或是由一个根结点加上两棵分别称为左子树和右子树的、互不交的二叉树组成。 根结点 右子树 A B E C F G D 左子树 逻辑结构:一对二(1:2) 基本特征: ① 每个结点最多只有两棵子树(不存在度大于2的结点); ② 左子树和右子树次序不能颠倒。 H K
基本形态: 一般的树有几种? 问:具有3个结点的二叉树可能有几种不同形态? 有5种
c e a d b f + / - - * 应用举例:可以用二叉树表示表达式 a+b*(c-d)-e/f
大家来思考 问题 ??? 回答: 度为2的有序树只有一个分支时没有左右之分;二叉树即使只有一个分支,也有左右之分。 一棵度为2的有序树与一棵二叉树有何区别?
二叉树的抽象数据类型定义 ADT BinaryTree{ 数据对象D: 数据关系R: 基本操作 P: }ADT BinaryTree D是具有相同特性的数据元素的集合。 若D=Φ,则R= Φ ; 若D≠Φ,则R= {H};存在二元关系: ① root 唯一 //关于根的说明 ② Dj∩Dk= Φ //关于子树不相交的说明 ③ …… //关于数据元素的说明 ④ ……//关于左子树和右子树的说明 //至少有20个,如返回某结点的左孩子,或中序遍历,等等
性质 1: 在二叉树的第i层上至多有2i-1 个结点。 (i≥1) 6.2.2 二叉树的性质 用归纳法证明: 归纳基: 归纳假设: 归纳证明: i = 1层时,只有一个根结点: 2i-1 = 20 = 1; 假设对所有的 j,1≤ j i,命题成立; 二叉树上每个结点至多有两棵子树, 则第 i 层的结点数 = 2i-2 2 = 2i-1。
性质 2 :深度为 k 的二叉树上至多含 2k-1 个结点(k≥1)。 证明: 基于上一条性质,深度为 k 的二叉树上的结点数至多为 20+21+ +2k-1 = 2k-1。 性质 3 :对任何一棵二叉树,若它含有n0 个叶子结点、n2 个度为2的结点,则必存在关系式:n0 = n2+1。 证明: 设 二叉树上结点总数 n = n0 + n1 + n2 又 二叉树上分支总数 b = n1+2n2 而 b = n-1 = n0 + n1 + n2 - 1 由此, n0 = n2 + 1 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 a b c d e f g h i j 两类特殊的二叉树: 满二叉树:指的是深度为k且含有2k-1个结点的二叉树。 完全二叉树:树中所含的 n 个结点和满二叉树中编号为 1 至 n 的结点一一对应。
性质 4 :具有 n 个结点的完全二叉树的深度为 log2n +1 。 证明: 设完全二叉树的深度为 k 则根据第二条性质得 2k-1≤ n < 2k 即 k-1 ≤ log2 n < k 因为 k 只能是整数,因此, k =log2n+ 1 。
性质 5 : 若对含 n 个结点的完全二叉树从上到下且从左至右进行 1至 n的编号,则对完全二叉树中任意一个编号为 i的结点:(1) 若 i=1,则该结点是二叉树的根,无双亲, 否则,编号为 i/2 的结点为其双亲结点;(2) 若 2i>n,则该结点无左孩子, 否则,编号为 2i 的结点为其左孩子结点;(3) 若 2i+1>n,则该结点无右孩子结点, 否则,编号为2i+1 的结点为其右孩子结点。
练习一下吧 1.将算术表达式((a+b)+c*(d+e)+f)*(g+h)转化为二叉树。 2.假设高度为H的二叉树上只有度为0和度为2的结点,问此类二叉树中的结点数可能达到的最大值和最小值各为多少?
练习一下吧 1.假定在一棵二叉树中,双分支结点数为15个,单分支结点数为32个,则叶子结点 数为 。 A. 15 B. 16 C. 17 D. 47 2.假定一棵二叉树的结点数为18个,则它的最小高度 。 A. 4 B. 5 C. 6 D. 18 3.在一棵二叉树中第五层上的结点数最多为 。 A. 8 B. 15 C. 16 D. 32 4.在一棵具有五层的满二叉树中,结点总数为 。 A. 31 B. 32 C. 33 D. 16 5.假定一棵二叉树的广义表表示为A(B(,D),C(E(G),F)),则该树的深度为, 度为0的结点数为 ,度为1的结点数为 ,度为2的结点数为 。
练习一下吧 6.如果结点A有三个兄弟,而且B是A的双亲,则B的出度是 。 A. 3 B. 4 C. 5 D. 1 7.一个深度为L的满K叉树有如下性质:第L层上的结点都是叶子结点,其余各层上每个结点都有K棵非空子树。如果按层次顺序从1开始对全部结点编号,编号为n的有右兄弟的条件是 。 A.(n-1) % k= =0 B.(n-1) % k!=0 C.n % k= =0 D.n % k!=0 8.在完全二叉树中,当i为奇数且不等于1时,结点i的左兄弟是结点 ,否则没有左兄弟。 A. 2i-1 B. i+1 C. 2i+1 D. i-1
小结 本小节主要讲了一下内容: 1.树的定义相关术语。 2.熟练掌握二叉树的结构特性,了解相应的证明方法。
6.2.3 二叉树的存储结构 一、 二叉树的顺序存储表示 二、二叉树的链式存储表示
一、 二叉树的顺序存储表示 所谓二叉树的顺序存储,就是用一组连续的存储单元存放二叉树中的结点。一般是按照二叉树结点从上至下、从左到右的顺序存储。 #define MAX_TREE_SIZE 100 // 二叉树的最大结点数 typedef TElemType SqBiTree[MAX_ TREE_SIZE]; // 0号单元存储根结点 SqBiTree bt; 0 A 2 例如: 1 B D 6 4 E C 13 F 0 1 2 3 4 5 6 7 8 9 10 11 12 13 A B D C E F
例: 4 1 1 2 3 2 3 5 6 7 4 5 6 8 9 7 8 9 10 10 9 1 2 3 4 5 6 7 8 910 1 2 3 4 0 5 6 7 8 0 0 910 完全二叉树 一般二叉树 的顺序表示 的顺序表示
二、二叉树的链式存储表示 1. 二叉链表 2.三叉链表 3.双亲链表 4.线索链表
1. 二叉链表 结点结构: root lchild data rchild A B D C E F
大家来思考 问题 ??? 回答: n+1个空指针 问题: 在具有n个结点的二叉树(k≥2)的二叉树链表表示中,有多少个空指针?
C 语言的类型描述如下: typedef struct BiTNode { // 结点结构 TElemType data; struct BiTNode *lchild, *rchild; // 左右孩子指针 } BiTNode, *BiTree; 结点结构: lchild data rchild
2、三叉链表 结点结构: parentlchild data rchild C 语言的类型描述如下: typedef struct TriTNode { // 结点结构 TElemType data; struct TriTNode *lchild, *rchild; // 左右孩子指针 struct TriTNode*parent; //双亲指针 } TriTNode, *TriTree;
B 2 C 0 A -1 D 2 E 3 F 4 3.双亲链表 结点结构: 0 1 2 3 4 5 6 L R R R L data parent LRTag
C语言描述 typedef struct BPTNode {// 结点结构 TElemType data; int*parent; // 指向双亲的指针 char LRTag; // 左、右孩子标志域 } BPTNode; typedef struct BPTree{// 树结构 BPTNode nodes[MAX_TREE_SIZE]; int num_node;// 结点数目 int root; // 根结点的位置 } BPTree;
大家来思考 问题 ??? 回答: (k-1)n+1个空指针 问题: 在具有n个结点的k叉树(k≥2)的k叉树链表表示中,有多少个空指针?
6.3 二叉树的遍历和线索二叉树 6.3.1 二叉树的遍历 6.3.2 线索二叉树
6.3.1 二叉树的遍历 一、问题的提出 “遍历”是任何类型均有的操作,对线性结构而言,只有一条搜索路径(因为每个结点均只有一个后继),故不需要另加讨论。而二叉树是非线性结构,每个结点有两个后继,则存在如何遍历即按什么样的搜索路径遍历的问题。 对“二叉树”而言,可以有三条搜索路径: • 1 先上后下的按层次遍历; • 2 先左(子树)后右(子树)的遍历; • 3 先右(子树)后左(子树)的遍历。
二、先左后右的遍历算法 先(根)序的遍历算法 中(根)序的遍历算法 后(根)序的遍历算法
DLR 先(根)序的遍历算法: 若二叉树为空树,则空操作;否则, (1)访问根结点; (2)先序遍历左子树; (3)先序遍历右子树。
LDR 中(根)序的遍历算法: 若二叉树为空树,则空操作;否则, (1)中序遍历左子树; (2)访问根结点; (3)中序遍历右子树。
后(根)序的遍历算法: 若二叉树为空树,则空操作;否则, (1)后序遍历左子树; (2)后序遍历右子树; (3)访问根结点。