第五章:树与二叉树(数据结构)
数据对象 D :D 是具有相同特性的数据元素的集合
数据关系 R :若 D 为空集,则称为空树;
否则:
( 1 )在 D 中存在唯一的称为根的数据元素 root ,
( 2 )当 n> 1 时,其余结点可分为 m ( m > 0 )个互不相交的有限集𝑇1 ,𝑇2, .…, 𝑇𝑚, 其中每一棵子集本身又是一棵符合本定义的树,称为根 root 的子树。
查找类:引用型 插入类:加工型 删除类:加工型
查找类:
Root(T); //求树的根结点
Value(T, cur_ e); //求当前结点的元素值
Parent(T, cur_ e); //求当前结点的双亲结点
LeftChild(T, cur_ e); //求当前结点的最左孩子
RightSibling(T, cur_e); // 求当前结点的右兄弟
TreeEmpty(T); //判定树是否为空树
TreeDepth(T); //求树的深度
TraverseTree( T, Visit() ); // 遍历
插入类:
InitTree(&T); 1初始化置空树
Create' Tree(& T, definition); 1按定义构造树
Assign(&T, cur_ e, value);/给当前结点赋值
InsertChild(&T, &p, i, c);//将以c为根的树插入为结点p的第i棵子树
删除类:
ClearTree(&T); //将树清空
DestroyTree(&T); // 销毁树的结构
DeleteChild(&T, &p, i);//删除结点p的第i棵子树
有向树:
( 1 )有确定的根,
( 2 )树根和子树根之间为有向关系。
有序树:
子树之间:确定的次序关系。
无序树:
子树之间 - 确定的次序关系。
线性结构 |
树形结构 |
第一个数据元素 (无前驱) |
根结点 (无前驱) |
最后一个数据元素 (无后继) |
多个叶子结点 (无后继) |
其它数据元素 (一个前驱、一个后继) |
其它数据元素 (一个前驱、多个后继) |
度为0的结点为叶子结点
8)在树结构中,一个结点的子树个数称为此结点的____
度
二叉树的定义:
一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根结点加上两棵分别称为左子树和右子树的、互不相交的二叉树组成。
特点:1)每个结点的度≤2;2)是有序树
若干术语
根——即根结点(没有前驱)
叶子——即终端结点(没有后继)
森林—指m棵不相交的树的集合
(例如删除A后的子树个数)
有序树——结点各子树从左至右有序,不能互换(左为第一)
无序树——结点各子树可互换位置。
双亲——即上层的那个结点,也叫父节点(直接前驱)
孩子——即下层结点的子树的根(直接后继)
兄弟——同一双亲下的同层结点(孩子之间互称兄弟)
堂兄弟——即双亲位于同一层的结点(但并非同一双亲)
祖先——即从根到该结点所经分支的所有结点
子孙——即该结点下层子树中的任一结点
线性结构 |
树结构 |
第一个数据元素 无前驱 |
根结点(只有一个)无双亲 |
最后一个数据元素 无后继 |
叶子结点(可以有多个)无孩子 |
其它数据元素 |
其它结点一中间结点 |
一个前驱,一个后继 |
一个双亲,多个孩子 |
一对一 |
一对多 |
度大于0的结点称为分支结点 度为0的结点称为叶子结点 |
![]() |
五种形态
二叉树的五种不同的形态
定义1 满二叉树(Full Binary Tree)
定义2 完全二叉树(Complete Binary Tree)
若设二叉树的深度为h,则共有h层。除第h层外,其它各层
(0~h-1)的结点数都达到最大个数,第h层从右向左连续缺若干
结点,这就是完全二叉树。
在二叉树中,叶子节点比度为2的结点多1的
𝑛2=𝑛0-1
叶字节点\(\lceil \frac{n+1}{2}\rceil\)
性质1 若二叉树的层次从1开始, 则在二叉树的第 i 层最多有 2i−1个结点。(i ≥1)
[证明用数学归纳法]
性质2 深度为k的二叉树最多有 2𝑘-1个结点。(k ≥1)
[证明用求等比级数前k项和的公式]
性质3 对任何一棵二叉树, 如果其叶结点个数为 n0 , 度为2的非叶结点个数为 n2 , 则有
n0=n2 +1
![]() |
n=n0+n1+n2 n=n1+2n2+1 |
两种方法:
方法一:总结点数=度为0结点+度为1的结点+度为2的结点
方法二:总结点数=1×度为1的结点+2×度为2的结点+1个根结点
性质4 具有n个结点的完全二叉树的深度为
⌊log2n⌋ +1
证明:设完全二叉树的深度为k,则有
2k−1 -1<n < 2k - 1
2k−1 <n < 2k
取对数 k-1 ≤ log2n <k
因为k为整数,所以k =⌊log2n⌋ +1
说明:常出现在选择题中
性质5 如果将一棵有n个结点的完全二叉树的结点按层序(自顶向下,同一层自左向右)连续编号1, 2, …, n,然后按此结点编号将树中各结点顺序地存放于一个一维数组中, 并简称编号为i的结点为结点i (1 ≤ i ≤ n)。则有以下关系:
①若i == 1, 则 i 是二叉树的根,无双亲
②若i > 1, 则 i 的双亲为⌊i /2⌋
③ 若2*i ≤ n, 则 i 的左孩子为2*i,否则无左孩子
④若2*i+1 ≤ n, 则 i 的右孩子为2*i+1,否则无右孩子
⑤ 若 i 为偶数, 且i != n, 则其右兄弟为i+1
⑥若 i 为奇数, 且i != 1, 则其左兄弟为i-1
i 所在层次为⌊log 2i⌋ +1
6、由3个结点所构成的二叉树有____种形态。
5种
设一棵完全二叉树共有500个结点,则此完全二叉树有多少个叶子结点,有多少个度为2的结点,有多少个只有左孩子
设二叉树中度bai为0结点个数为n0,度du为1的结点个数为zhin1,度为2的结点个数为n2
于是 n0 + n1 + n2 = 500,由二叉树性dao质n0 = n2 + 1,代入得到:2n2 + 1 + n1 = 500
显然n1是奇数,考虑到完全二叉树中度为1结点个数最多为1,因此n1 = 1
因此n2 = 249,n0 = 250,只有左孩子的结点个数为1
考虑到完全二叉树中没有结点只有右孩子,因此只有右孩子的结点个数为0
一棵具有257个结点的完全二叉树,它的深度为
首先是完全二叉树:
2的8次方为256,2的9次方为512
满二叉树的结点树为2的N次方-1
所以深度为8的满二叉树的结点个数为255
深度为9的满二叉树的结点个数为511
所以深度为9
74.数据结构王道最后8套题第七套第一,6题050页 6.下列说法中,正确的是( )。 |
A.对于有n 个结点的二叉树,其高度为 ⎡log2n⎤ |
B.完全二叉树中,若一个结点没有左孩子,则它必是叶结点 |
C.高度为h(h>0)的完全二叉树对应的森林所含的树的个数一定是 h |
D.一棵树中的叶子数一定等于其对应的二叉树的叶子数 |
B |
6.B。 【解析】若结点数为 n 的二叉树是一棵单支树,其高度为 n,只有完全二叉树才具有A性质。完全二叉树中最多只存在一个度为1的结点且该结点只有左孩子,若不存在左孩子,则一定也不存在右孩子,因此必是叶结点,B 正确。只有满二叉树才具有 C 性质,如下图所示: 在树转换为二叉树时,若有几个叶子结点有共同的双亲结点,则转换为二叉树后只有一个叶子(最右边的叶子),如下图所示,D 错误。 |
74.数据结构王道最后8套题第五套第一,4题033页 4.一般说来,若深度为k的n个结点的二叉树具有最小路径长度时,第k层(根为第1层)上的结点数为()。 |
A. n-2k+1 |
B. n-2k-1+1 |
C. n-2+n |
D. n-2k-1 |
B |
4. B。 A .1-21+1=0 B. 1-21−1+1=1 C. 1-2+1=0 D. 1-21-1=-2 只有b符合 解析]考查完全二义树。树的路径长度是从根结点到树中每结点的路径长度之和。 对于结点数固定为n,在二义树每层(除最后层)上的结点个数都饱和的一义树的路径长度最短。在结点数目相同的又树中,完全二叉树的路径长度最短,最后一层(第k层)上的叶结点个数为n-(2𝑘−1-1)=n-2𝑘−1+1。 |
74.计算机组成原理王道最后8套题第四套第一,4题025页 4.若一棵二叉树中有24个叶结点,有28个仅有一个孩子的结点,则该二叉树的总结点数为() |
A.70 |
B. 73 |
C. 75 |
D.77 |
C |
4. C。 [解析]考察二叉树结点数量之间关系的性质。按照二叉树结点数的关系有No=N2+1, 而题中有24个叶子节点即为有24个度为0的结点,有28个仅有一个孩子的结点即为有28个度为1的结点,按照公式No=N2+1, 即N2=N0-1=24- 1=23, 所以树的结点的总数为N0+N1+N2=24+28+23=75,答案选C。 |
74.数据结构王道最后8套题第一套第一,3题001页 3,已知A[1...N]是一棵顺序存储的完全二叉树,9号结点和11号结点共同的祖先是( ) |
A.4 |
B.6 |
C.2 |
D.8 |
C |
3. C. [解析]考察完全二叉树顺序存储的性质。根据顺序存储的完全二叉树子结点与父结点之间的倍数关系推导。K号结点的祖先为[k/2],计算两个结点i, j共同的祖先算法可归结如下: 1)若i!=j则执行2,否则寻找结束,共同父节点为(或j) 2)取max{I,j}执行操作(以i为例),i-[i/2], 然后跳回1)。根据算法即可算出答案为2,选C. |
1、顺序存储结构(数组表示)
存树的数据和关系才能还原这棵树.
①连续②编号法存储③空间有浪费的(一般二叉树)
1 |
2 |
3 |
4 5 6 |
7 |
8…14 |
15 |
16…30 |
31 |
31 |
|
12 |
… |
17 |
… |
88 |
… |
49 |
左分支和右分支相比,右分支更浪费,右编号大
2.链式存储模式
typedef struct BiTNode{ //二叉链表的定义
TElemType data;
Struct BiTNode *lchild,*rchild;
}BiTNode, *BiTree;
逻辑结构(a)存储计算机形成存储结构(b) ,三叉链表指向双亲的指针(C)
练习
在n个结点的二叉链表中,有多少个空指针域?
分析:答案n+1, 可以参考上图二叉链表表示的(a)和(b)事例。
必有2n个链域。除根结点外,
每个结点有且仅有一个双亲,所以
只会有n -1个结点的链域存放指针.
指向非空子女结点。
空指针数目=2n -(n-1)=n+1
二叉树是非线性数据结构,所以() |
A.它不能用顺序存储结构存储 |
B.它不能用链式存储结构存储; |
C.它能采用顺序存储结构和链式存储结构存储 |
D.它既不能使用顺序存储结构和也不能使用链式存储结构存储 |
C |
答案是C 说明: 一般而言,完全二叉树(包括满二叉树)使用顺序存储 普通二叉树一般用二叉链表或者三叉链表存储 |
5.3二叉树的遍历(Traversing Binary Tree)
所谓树的遍历,就是按某种次序访问树中的结点,要求每个
结点访问一次且仅访问一次。
遍历的结果:产生一个关于结点的线性序列。
设访问根结点记作 D
遍历根的左子树记作 L
遍历根的右子树记作 R
则可能的遍历次序有
先序 DLR DRL 逆先序
中序 LDR RDL 逆中序
后序 LRD RLD 逆后序
14.数据结构王道考研第四章:树与二叉树.第三节:二叉树的遍历和线索二叉树第21页,第二,3题
编写后序遍历二叉树非递归算去。
void PostOrder(BiTree T){
InitStack(S);
BiTree p=T;
r=NULL; //记录最近访问过的结点
while(p||!IsEmpty(S)){
if(p){ //走到最左边
push(S,p);
p=p->lchild;
} else { //遍历完左子树,向右
GetTop(S,p); //取栈顶结点
if(p->rchild&&p->rchild!=r){ //如果右子树存在,且未访问过
p=p->rchild; //转向右
push(S,p); //压入栈
p=p->lchild; //再走到最左
} else { //否则弹出结点并访问
pop(S,p); //将结点弹出
visit(p->data); //访问该结点
r=p; //记录最近访问过的结点
p=NULL;
}
} //else
} //while
}
74.数据结构王道最后8套题第八套第一,5题057页 5.由某种序列可以唯一的确定一棵二叉树,不能唯一的确定一棵二叉树是( )。 |
A.先序序列和中序序列 |
B.后序序列和中序序列 |
C.中序序列和层序序列 |
D.先序序列和层序序列 |
D |
5.D。 【解析】考查由遍历序列构造二叉树。由遍历序列构造二叉树的思想就是找到根结点,然后将序列划分成左、右子树,如此递归地进行下去。前序序列和中序序列、后序序列和中序序列、或中序序列和层序序列可唯一确定一个二叉树。先序序列和层序序列不能唯一的确定一棵二叉树,层序序列第 1 次访问根结点,先序序列为 NLR,虽然能找到根结点,但无法划分左、右子树。如上图所示的 5 棵不同的二叉树,其对应的先序序列和层序序列是相同的。 |
74.数据结构王道最后8套题第五套第一,5题033页 5.前序遍历和中序遍历结果相同的二叉树为( ) 。 I.只有根结点的二叉树 II.根结点无右孩子的二叉树 III.所有结点只有左子树的二叉树 IV.所有结点只有右子树的二叉树 |
A.仅有I |
B. I、II和IV |
C. I和III |
D. I和IV. |
D |
5.D[解析]考查二叉树的遍历。 解法一:对于1,显然任何遍历都相同。对于II,根结点无右孩子,此时前序遍历先遍历根结点,中序遍历最后遍历根结点,所以不相同。对于II,是一棵左单支树,前序遍历和后序遍历的序列相反。对于IV,所有结点只有右子树的右单支树,前序遍历和中序遍历的序列相同。选D。 解法二:若树中某棵子树存在左子树,那么中序通历一定会先遍历左子树才会遍历这颗子树本身,而先序遍历则先遍历这棵本身,所以只要树中某个结点存在左子树便是不符合要求的,所以任何一颗子树 都没有左子树的树符合题目要求,那么I和IV符合要求。 |
5.3.1先序遍历 (Preorder Traversal)
先序遍历二叉树算法的框架是
n 若二叉树为空,则空操作;
n 否则
u 访问根结点 (D);
u 访问根结点 (D);
u 先序遍历左子树 (L);
u 先序遍历右子树 (R)。
Status PreOrderTraverse(BiTree T) {
if (T == NULL)return OK;//空二叉树
else {
visit(T);//访问根结点
PreOrderTraverse(T->lchild);//递归遍历左子树
PreOrderTraverse(T->rchild);//递归遍历右子树
}
}
遍历结果(前缀表达式)
遍历结果(前缀表达式)
- + a * b - c d / e f
遍历结果(中缀表达式)
Status lnOrderTraverse(BiTree T) {
if (T == NULL)return OK; // 空二叉树
else {
InOrderTraverse(T->lchild);//递归遍历左子树
visit(T);//访问根结点;
InOrderTraverse(T->rchild);//递归遍历右子树
}
}
遍历结果(中缀表达式)
a + b * c - d - e / f
5.3.3后序遍历 (Postorder Traversal)
1.后序遍历二叉树算法的框架是
n 若二叉树为空,则空操作;
n 否则
u 后序遍历左子树 (L);
u 后序遍历左子树 (L);
u 后序遍历右子树 (R);
u 访问根结点 (D)
Status PostOrderTraverse(BiTree T) {
if (T == NULL) return OK;//空二叉树
else {
PostOrderTraverse(T->lchild);//递归遍历左子树个
PostOrderTraverse(T->rchild);//递归遍历右子树
visit(T);//访问根结点
}
}
2.算法与数据结构的关系
遍历结果(后缀表达式)
a b c d - * + e f / -
由二叉树的先序序列和中序序列可唯一地确定一棵二叉树。例, 先
序序列 { ABHFDECKG } 和中序序列 { HBDFAEKCG }, 构造二叉树过程如下:
后缀表达式,符号优先级
操作符 |
# |
( |
*,/ |
+,- |
) |
isp(栈內) |
0 |
1 |
5 |
3 |
6 |
icp(栈外) |
0 |
6 |
4 |
2 |
1 |
2)如何可唯一地确定一棵二叉树?
先序遍历+中序遍历或后序遍历+中序遍历均可唯一地确定一棵二叉树
3)二叉树的二叉链表存储结构中,有多少个指针域未利用?
二叉树的二叉链表存储结构中,有多n+1个指针域未利用已经使用的有n-1个指针域,共有2n个指针域
算法思想:
1)初始将根入队并访问根结点,然后出队;
2)若有左子树,则将左子树的根入队;
3)若有右子树,则将右子树的根入队;
4)然后出队,访问该结点;
5)反复该过程直到队列空为止。
void LevelOrder(BTNode *b) {
BTNode* p; SqQueue *qu;
lnitQueue(qu);
// 初始化队列
enQueue(qu,b);
//根结点指针进入队列
while (!QueueEmpty(qu)) {
// 队不为空,则循环
deQueue(qu,p);//出队结点p
printf("%c ",p->data);
//访问结点p
if (p->lchild != NULL)enQueue(qu,p->lchild);
//有左孩子时将其进队
if (p->rchild != NULL)enQueue(qu, p->rchild);
//有右孩子时将其进队
}
}
线索 (Thread): 指向结点前驱和后继的指针
若结点有左孩子,则lchild指示其左孩子,否则lchild中存储该结点的前驱结点的指针;
(Threaded Binary Tree)
若结点有右孩子,则rchild指示其右孩子,否则rchild中存储指向该结点的后继结点的指针
实质:对一个非线性结构进行线性化操作,使每个结点(除第一和最后一个外)在这些线性序列中有且仅有一个直接前驱和直接后继。
说明:在线索树中的前驱和后继是指按某种次序遍历所得到的序列中的前驱和后继
线索二叉树及其线索链表的表示
ltag = 0, lchild为左孩子指针
ltag = 1, lchild为前驱线索
rtag = 0, rchild为右孩子指针
rtag = 1, rchild为后继指针
带表头结点的中序穿线链表
![]() |
![]() |
后续线索化如上
有左右孩子将标志置为0,没有左右孩子,将标志置为1.
路径长度 (Path Length):两个结点之间的路径长度是连接两结点的路径上的分支数。树的路径长度是各结点到根结点的路径长度之和。
具有不同路径长度的二叉树
具有不同带权路径长度的扩充二叉树
从(a)可以看出满二叉树不一定是哈夫曼树
从(c)(d)看出具有相同带权结点的哈夫曼树不惟一
结论:
哈夫曼树的结点的度数为0或2,没有度为1的结点。
包含n棵树的森林要经过n-1次合并才能形成哈夫曼树,共产生n-1个新结点
包含n个叶子结点的哈夫曼树中共有2n- 1个结点。
带权路径长度达到最小的二叉树即为赫夫曼(最优二叉树)。
在赫夫曼树中,权值大的结点离根最近。
赫夫曼树的构造过程
74.数据结构王道最后8套题第八套第一,7题057页 7.对于一组权值都相等的 16 个字母,构造相应的哈夫曼树,这棵哈夫曼树是一棵( )。 |
A.完全二叉树 |
B.一般二叉树 |
C.满二叉树 |
D.以上都不正确 |
C |
7.C。 【解析】考查哈夫曼树的构造。将 16 个权值相等(设为m)的字母看成 16个独立的结点;从中任选两个结点构成一棵新的二叉树(共 8 棵),新树的权值为 2m;再从 8 棵树中任选 2 棵构成新的二叉树(共 4 棵),新树的权值为 4m,……,如此继续,刚好能构成一棵满二叉树 |
主要用途是实现数据压缩。
设给出一段报文:
CAST CAST SAT AT A TASA
字符集合是 { C, A, S, T },各个字符出现的频度(次数)是 W={ 2, 7, 4, 5 }。
若给每个字符以等长编码
A: 00 T : 10 C : 01 S : 11
则总编码长度为 ( 2+7+4+5 ) * 2 = 36.
若按各个字符出现的概率不同而给予不等长编,可望减少总编码长度。
因各字符出现的概率为{ 2/18, 7/18, 4/18, 5/18}。
化整为 { 2, 7, 4, 5 },以它们为各叶结点上的权值,建立赫夫曼树。左分支赋 0,右分支赋 1,得赫夫曼编码(变长编码)。
A: 0 T : 10 C : 110 S : 111
它的总编码长度:7*1+5*2+( 2+4 )*3 = 35。比等长编码的情形要短。
总编码长度正好等于赫夫曼树的带权路径长度WPL。
赫夫曼编码是一种无前缀的编码。解码时不会混淆。
假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 n个权值分别
设为 w 1 ,w 2 ,…,w n ,则哈夫曼树的构造规则为:
(1) 将w 1 ,w 2 ,…,w n 看成是有n 棵树的森林(每棵树仅有一个结点);
(2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、
右子树,且新树的根结点权值为其左、右子树根结点权值之和;
(3)从森林中删除选取的两棵树,并将新树加入森林;
(4)重复(2)、(3)步,直到森林中只剩一棵树为止,该树即为我们所求得
的哈夫曼树。
下面给出哈夫曼树的构造过程,假设给定的叶子结点的权分别为1,5,7,3,
则构造哈夫曼树过程如图根据构造过程:n 个权值构造哈夫曼树需n-1次合并,每次合并,森林中的树数目减1,最后森林中只剩下一棵树,即为我们求得的哈夫曼树。
1,双亲表示法
它是以一组连续的存储单元来存放树中的结点,每个结点有两个域:
一个是data域,存放结点信息,另一个是parent域,用来存放双亲的位
置(指针)。
该结构的具体描述见图5-21。
74.数据结构王道最后8套题第二套第一,6题009页 6.由4棵树组成的森林中,第一、第二、第三和第四棵树中的结点数分别为30、10、20、5,当把森林转换成叉树后, 对应二叉树中根结 点的右子树的左子树的结点数为 ()。 |
A.29 |
B.9 |
C.25 |
D.19 |
B |
6. B。
|
2.孩子表示法
将一个结点所有孩子链接成一个单链表形,而树中有若干个结点,故有若干个单链表,每个单链表有一个表头结点,所有表头结点用一个数组来描述,具体描述参见图5-22
图 5-22树的孩子表示法(图6-2 1(a)中树)示意图
3.双亲孩子表示法
将第1、2两种方法结合起来,则得到双亲孩子表示法,具体参见图5-23
图 5-23 树 的 双 亲 孩 子 表 示 法 示 意 图
4.孩子兄弟法
类似于二叉链表,但第一根链指向第一个孩子,第二根链指向下一
个兄弟。将图5-21(a)的树用孩子兄弟表示法表示,见图5-24
1.树转换成二叉树
可以分为三步:
(1) 连线
指相邻兄弟之间连线。
(2) 抹线
指抹掉双亲与除左孩子外其它孩子之间的连线。
(3) 旋转
只需将树作适当的旋转。
连线 |
兄弟相连 |
抹线 |
长兄为父 |
旋转 |
孩子靠左 |
具体实现过程见图5-25。
图 5-25 树 转 换 成 二 叉 树 示 意 图
2.森林转换成二叉树
(1) 将森林中每一棵树分别转换成二叉树这在刚才的树转换成二叉树中已经介绍过。
(2)合并
使第n棵树接入到第n-1棵的右边并成为它的右子树,第 n-1 棵二叉树接入到第n-2 棵的右边并成为它的右子树,…,第2棵二叉树接入到第1棵的右边并成为它的右子树,直到最后剩下一棵二叉树为止
3.二叉树还原成树或森林
(1) 右链断开
将二叉树的根结点的右链及右链的右链等全部断开,得到若干棵无右子
树的二叉树。
具体操作见图5-27(b)。
(2) 二叉树还原成树
将(1)中得到的每一棵二叉树都还原成树(与树转换成二叉树的步骤
刚好相反)。
具体操作步骤见图5-27(c)。
图5-27(c) 二叉树还原成树或森林
把一棵树转换为二叉树后,这棵二叉树的形态是(). |
A、唯一的,且根结点没有右孩子 |
B、有多种,但根结点都没有右孩子 |
C、唯一的,且根结点可能有右孩子 |
D、有多种,且根结点可能有右孩子 |
A |
A.树转换成二叉树,根节点是没有右孩子的,这由转换规则应该不难理解,且转换规则是唯一的,所以转换成的二叉树是唯一的 |
在树和森林中,一个结点可能有两棵以上的子树,所以不宜讨论它
们的中序遍历, 即树和森林只有先序遍历和后序遍历。
1.树的遍历
\(\color{green}{树的遍历} \begin{equation}\begin{cases} \color{blue}{深度优先遍历,} \color{red}{(先根,后根)}\\ \color{blue}{广度优先遍历. } \color{red}{(层次)}\\ \end{cases}\end{equation}\)
先根遍历 Ø访问根结点;
Ø依次先根遍历根结点的每棵子树。
|
后根遍历
Ø依次后根遍历根结点的每棵子树;
Ø访问根结点。
|
树没有中序遍历(因子树不分左右)
例如:
![]() |
先根序列:a b c d e 后根序列:b d c e a |
讨论:树若采用“先转换,后遍历”方式,结果是否一样?
![]() |
先序遍历:a b c d e 中序遍历:b d c e a 后序遍历:d e c b a 树的先根序列:a b c d e 树的后根序列:b d c e a |
结论:
1. 树的先根遍历与二叉树的先序遍历相同;
2. 树的后根遍历相当于二叉树的中序遍历;
3. 树没有中序遍历,因为子树无左右之分。
2.森林的遍历
\({\color{green}{\textbf{森林的遍历}}} \begin{equation}\begin{cases} {\color{peru}{\textbf{深度优先遍历,}}} \color{red}{(先根,中根)}\\ {\color{peru}{\textbf{广度优先遍历. }}} \color{red}{(层次)}\\ \end{cases}\end{equation}\)
先根遍历 Ø若森林为空,返回;
Ø访问森林中第一棵树的根结点;
Ø先根遍历第一棵树的根结点的子树森林;
Ø先根遍历除去第一棵树之后剩余的树构成的森林。
|
•中根遍历
Ø若森林为空,返回;
Ø中根遍历森林中第一棵树的根结点的子树森林;
Ø访问第一棵树的根结点;
Ø中根遍历除去第一棵树之后剩余的树构成的森林。
|
例如:
![]() |
先根序列:A B C D E F G H I J 中根序列:B C D A F E H J I G |
讨论:若采用“先转换,后遍历”方式,结果是否相同?
![]() |
先序序列:A B C D E F G H I J 中序序列:B C D A F E H J I G |
结论:森林的先根和中根遍历在两种方式下的结果相同。
遍历序列关系
树 |
森林 |
二叉树 |
先根遍历 |
先序遍历 |
先序遍历 |
后根遍历 |
中序遍历 |
中序遍历 |
评论列表 (0 条评论)