第7课 树与二叉树的转换
数据结构有序树转二叉树(树的遍历)

数据结构有序树转⼆叉树(树的遍历)Description计算输⼊有序树的深度和有序树转化为⼆叉树之后树的深度。
Input输⼊包含多组数据。
每组数据第⼀⾏为⼀个整数n(2<=n<=30000)代表节点的数量,接下来n-1⾏,两个整数a、b代表a是b的⽗亲结点。
Output输出当前树的深度和转化成⼆叉树之后的深度。
Sample Input51 51 35 21 4Sample Output3 4HINTAppend Code析:这个题很好说,只要遍历⼀次就能得到答案,由于要先有序树转成⼆叉树,我也没听过,我百度了⼀下怎么转,看到百度百科中有,我总结⼀下就是,左⼉⼦,右兄弟,和那个字典树有的⼀拼,也就是左结点是⼉⼦结点,⽽右结点是兄弟结点,那么我们可以⽤两个参数来记录深度,⼆叉树既然是右兄弟,那么同⼀深度的就会多⼀层,加1,这样最⼤的就是答案。
代码如下:#pragma comment(linker, "/STACK:1024000000,1024000000")#include <cstdio>#include <string>#include <cstdlib>#include <cmath>#include <iostream>#include <cstring>#include <set>#include <queue>#include <algorithm>#include <vector>#include <map>#include <cctype>#include <cmath>#include <stack>#define debug puts("+++++")//#include <tr1/unordered_map>#define freopenr freopen("in.txt", "r", stdin)#define freopenw freopen("out.txt", "w", stdout)using namespace std;//using namespace std :: tr1;typedef long long LL;typedef pair<int, int> P;const int INF = 0x3f3f3f3f;const double inf = 0x3f3f3f3f3f3f;const LL LNF = 0x3f3f3f3f3f3f;const double PI = acos(-1.0);const double eps = 1e-8;const int maxn = 3e4 + 5;const LL mod = 1e3 + 7;const int N = 1e6 + 5;const int dr[] = {-1, 0, 1, 0, 1, 1, -1, -1};const int dc[] = {0, 1, 0, -1, 1, -1, 1, -1};const char *Hex[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"}; inline LL gcd(LL a, LL b){ return b == 0 ? a : gcd(b, a%b); }inline int gcd(int a, int b){ return b == 0 ? a : gcd(b, a%b); }inline int lcm(int a, int b){ return a * b / gcd(a, b); }int n, m;const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};inline int Min(int a, int b){ return a < b ? a : b; }inline int Max(int a, int b){ return a > b ? a : b; }inline LL Min(LL a, LL b){ return a < b ? a : b; }inline LL Max(LL a, LL b){ return a > b ? a : b; }inline bool is_in(int r, int c){return r >= 0 && r < n && c >= 0 && c < m;}vector<int> G[maxn];bool in[maxn];int ans1, ans2;void dfs(int u, int cnt1, int cnt2){ans1 = Max(ans1, cnt1);ans2 = Max(ans2, cnt2);for(int i = 0; i < G[u].size(); ++i)dfs(G[u][i], cnt1+1, cnt2+i+1);}int main(){while(scanf("%d", &n) == 1){for(int i = 0; i <= n; ++i) G[i].clear(), in[i] = 0;int u, v;for(int i = 1; i < n; ++i){scanf("%d %d", &u, &v);G[u].push_back(v);in[v] = true;}ans1 = ans2 = 0;for(int i = 1; i <= n; ++i) if(!in[i]){dfs(i, 1, 1); break;}printf("%d %d\n", ans1, ans2);}return 0;}。
《数据结构》综合练习

综合练习一、单项选择题1.数据在计算机存储器内表示时,物理地址与逻辑地址不相同的,称之为(C ).A.存储结构B。
逻辑结构C.链式存储结构D。
顺序存储结构2.设语句x++的时间是单位时间,则以下语句的时间复杂度为( B ).for(i=1; i<=n; i++)for(j=i;j〈=n;j++)x++;A。
O(1) B.O(2n)C。
O(n) D.O(3n)3.链式存储结构的最大优点是( D )。
A。
便于随机存取B。
存储密度高C.无需预分配空间D.便于进行插入和删除操作4.假设在顺序表{a0,a1,……,a n-1}中,每一个数据元素所占的存储单元的数目为4,且第0个数据元素的存储地址为100,则第7个数据元素的存储地址是( D ).A。
106 B. 107 C。
124 D.1285.在线性表中若经常要存取第i个数据元素及其前趋,则宜采用( A )存储方式.A.顺序表B. 带头结点的单链表C。
不带头结点的单链表 D. 循环单链表6.在链表中若经常要删除表中最后一个结点或在最后一个结点之后插入一个新结点,则宜采用( C )存储方式。
A.顺序表B。
用头指针标识的循环单链表C。
用尾指针标识的循环单链表D。
双向链表7.在一个含有n个结点的有序单链表中插入一个新结点,使单链表仍然保持有序的算法的时间复杂度是( C )。
O(1) B。
O(log2n) C。
O(n) D。
O(n2)8.要将一个顺序表{a0,a1,……,a n—1}中第i个数据元素a i(0≤i≤n—1)删除,需要移动( B )个数据元素。
A.i B。
n—i-1 C. n-i D. n—i+19.在栈中存取数据的原则是( B )。
A。
先进先出 B。
先进后出C。
后进后出 D。
没有限制10.若将整数1、2、3、4依次进栈,则不可能得到的出栈序列是( D )。
A.1234 B. 1324 C. 4321 D. 142311.在链栈中,进行出栈操作时(B )。
第7章树和二叉树(2)-数据结构教程(Java语言描述)-李春葆-清华大学出版社

二叉树也称为二分树,它是有限的结点集合,这个集合或者是空,或者由 一个根结点和两棵互不相交的称为左子树和右子树的二叉树组成。 二叉树中许多概念与树中的概念相同。 在含n个结点的二叉树中,所有结点的度小于等于2,通常用n0表示叶子结 点个数,n1表示单分支结点个数,n2表示双分支结与度为2的树是不同的。
度为2的树至少有3个结点,而二叉树的结点数可以为0。 度为2的树不区分子树的次序,而二叉树中的每个结点最多有 两个孩子结点,且必须要区分左右子树,即使在结点只有一棵 子树的情况下也要明确指出该子树是左子树还是右子树。
2/35
归纳起来,二叉树的5种形态:
Ø
4/35
3. 满二叉树和完全二叉树
在一棵二叉树中,如果所有分支结点都有左孩子结点和右孩子结点,并且 叶子结点都集中在二叉树的最下一层,这样的二叉树称为满二叉树。
可以对满二叉树的结点进行层序编号,约定编号从树根为1开始,按照层 数从小到大、同一层从左到右的次序进行。
满二叉树也可以从结点个数和树高度之间的关系来定义,即一棵高度为h 且有2h-1个结点的二叉树称为满二叉树。
R={r} r={<ai,aj> | ai,aj∈D, 1≤i,j≤n,当n=0时,称为空二叉树;否则其中
有一个根结点,其他结点构成根结点的互不相交的左、右子树,该 左、右两棵子树也是二叉树 } 基本运算: void CreateBTree(string str):根据二叉树的括号表示串建立其存储结构。 String toString():返回由二叉树树转换的括号表示串。 BTNode FindNode(x):在二叉树中查找值为x的结点。 int Height():求二叉树的高度。 … }
5
E
树与二叉树的转换

删除它与其它孩子
结点之间的连线
注意:第一个孩子是二叉树
结点的左孩子,兄弟转换过 来的孩子是结点的右孩子
第二部分 新课讲授
第二部分 新课讲授
2、二叉树转换为树 加线
若某结点的左孩子结点 存在,则将这个左孩子 的右孩子结点、右孩子 的右孩子结点、右孩子 的右孩子的右孩子结点 等,就是左孩子的n个 右孩子结点都作为些结 点的孩子,将该结点与 这些右孩子结点用线连 接起来去线ຫໍສະໝຸດ 层次调整删除原二叉树中
有所结点与其右
逆时针旋转45 度,使之结构 层次分明
孩子结点的连线
第二部分 新课讲授
第三部分 总结反思
树到二叉树
70% 30%
树中的长子关系变成左 儿子关系;兄弟关系变 成右儿子关系。
二叉树到树
40%
二叉树中的左儿子关系 变成长子关系,右儿子 关系变成兄弟关系。
第三部分 总结反思
多了,因些很多性质和算法都被研究了出来。那么树
能不能转换成二叉树去研究呢? 答案是:能
第一部分 问题引入
第二部分 新课讲授
1、树转换为二叉树
加线
去线
层次调整
对树中每个结点,
在所有兄弟结点 之间加一条连线 只保留它与第一个 孩子结点的连线,
以树的根结点为轴心,将整
棵树顺时针旋转一定的角度, 使之结构层次分明。
思考: 如果不是一棵树,而是多棵树,
也就是森林,如何转换为二叉树?
感谢聆听 敬请指正
PPT模板下载:/moban/ 行业PPT模板:/hangye/ 节日PPT模板:/jieri/ PPT素材下载:/sucai/ PPT背景图片:/beijing/ PPT图表下载:/tubiao/ 优秀PPT下载:/xiazai/ PPT教程: www.1ppt.c om/powerpoint/ Word教程: /word/ Excel 教程:www.1ppt.c om/excel/ 资料下载:/ziliao/ PPT课件下载:/kejian/ 范文下载:/fanwen/ 试卷下载:www.1ppt.c om/shiti / 教案下载:/jiaoan/ PPT论坛:
《数据结构》课程教学大纲

《数据结构》课程教学大纲课程类别:专业基础课适用专业:计算机应用技术适用层次:高起专适用教育形式:成人教育考核形式:考试所属学院:计算机科学与技术学院先修课程:C语言程序设计一、课程简介《数据结构》课程是计算机专业的核心基础课程,是一门理论与实践相结合的课程,整个计算机专业教学体系中处于举足轻重的地位。
数据结构是程序设计(特别是非数值计算的程序设计)的基础,也是设计和实现编译程序、操作系统、数据库系统及其它系统程序和大型应用程序的重要基础。
基于该门课程的重要性,现在该课程已经是计算机相关专业研究生考试必考专业课之一,是反映学生数据抽象能力、编程能力的重要体现。
二、课程学习目标通过本课程的学习,使学生具备下列能力:1、能够理解常用数据结构和算法的基本思路、思考方法、使用场合以及算法设计中考虑的各种因素,能运用于非数值型计算问题的建模和算法设计;深入体会经典算法的思路和分析解决问题的方法,能运用于解决其他领域的相关问题。
2、能够针对基本数据结构和算法方面的特定问题进行分析或推导,分析相应的逻辑结构、选择合适的物理结构或给出问题的解;能对简单算法进行复杂度分析。
3、能针对特定问题需求和给定的数据结构进行算法设计。
三、与其他课程的关系数据结构是计算机及其相关专业的专业基础课,是《操作系统》、《数据库原理》等课程的先导课。
四、课程主要内容和基本要求第1单元数据结构及算法性能分析『知识点』本章作为本课程的绪论部分,主要介绍数据结构课程的研究内容,以及数据结构课程中用到的与课程内容相关的概念和基本术语。
另外,在本章还重点介绍了算法的概念、算法的特性以及算法设计的基本要求,分析算法的方法。
本章重点讲解数据结构的相关概念以及算法及其算法分析。
『基本要求』1、识记:数据、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构、数据类型、抽象数据类型等基本概念。
2、领会:顺序存储结构和链式存储结构。
3、简单应用:能够实现顺序存储结构和链式存储结构,并在简单问题中应用。
树和二叉树——精选推荐

第6章 树和二叉树内容概要:本章主要介绍树,二叉树,最优二叉树的相关概念和操作,存储结构和相应的操作,并在综合应用设计中,给出了对应算法的C 语言实现。
教学目标1.理解各种树和森林与二叉树的相应操作。
2.熟练掌握二叉树的各种遍历算法,并能灵活运用遍历算法实现二叉树的其他操作。
3.熟练掌握二叉树和树的各种存储结构及其建立的算法。
4.掌握哈夫曼编码的方法。
5.通过综合应用设计,掌握各种算法的C 语言实现过程。
基本知识点:树和二叉树的定义、二叉树的存储表示、二叉树的遍历以及其它操作的实现、树和森林的存储表示、树和森林的遍历以及其它操作的实现、最优树和赫夫曼编码重点:二叉树的性质、二叉树的遍历及其应用,构造哈夫曼树。
难点:编写实现二叉树和树的各种操作的递归算法。
本章知识体系结构:课时安排:6个课时树的定义 树树的性质 树的逻辑表示法 树形表示法 树的存储结构 双亲存储结构 文氏表示法凹入表示法 括号表示法 孩子存储结构 孩子双亲存储结构二叉树二叉树的定义 二叉树的性质二叉树的逻辑表示法(采用树的逻辑表示法)二叉树的存储结构二叉树的顺序存储结构先序遍历 中序遍历 后序遍历二叉树的遍历 二叉树的链式存储结构(二叉链) 由先序序列和中序序列构造二叉树 由中序序列和后序序列构造二叉树二叉树的构造 二叉树的线索化 哈夫曼树二叉树和树之间的差别 二叉树与树、森林之间的转换二叉树和树课程数据结构教学教具多媒体课件学时2班级06网络教学日期/课时 /2课时教学单元第6章树和二叉树教学方法讲授(PPT)教学目标掌握树、二叉树的基本概念和术语,二叉树的性质教学重点二叉树的定义、二叉树的性质、链式存储结构教学难点二叉树的性质、链式存储二叉树的基本操作组织教学一、树的定义二、树的基本概念三、二叉树的定义、性质四、二叉树的顺序存储结构和链式存储结构五、小结作业复习本讲内容并预习下一讲内容课堂情况及课后分析课程数据结构教学教具多媒体课件学时2班级06网络教学日期/课时 /2课时教学单元第6章树和二叉树教学方法讲授(PPT)教学目标掌握二叉树遍历的三种方法及二叉树的基本操作教学重点二叉树的遍历算法教学难点中序与后序遍历的非递归算法组织教学一、复习二叉树的定义二、遍历二叉树的三种方法三、递归法遍历二叉树四、二叉树的基本操作五、总结作业复习本讲内容并预习下一讲内容课堂情况及课后分析课程数据结构教学教具多媒体课件学时2班级06网络教学日期/课时 /2课时教学单元第6章树和二叉树教学方法讲授(PPT)教学目标理解树与森林的转换,掌握哈夫曼树教学重点哈夫曼树教学难点树与森林的转换组织教学一、导入二、树与森林三、哈夫曼树四、小结作业习题6课堂情况及课后分析前面几章讨论的数据结构都属于线性结构,线性结构的特点是逻辑结构简单,易于进行查找、插入和删除等操作,可用于描述客观世界中具有单一前驱和后继的数据关系。
数据结构习题及答案与实验指导(树和森林)7

第7章树和森林树形结构是一类重要的非线性结构。
树形结构的特点是结点之间具有层次关系。
本章介绍树的定义、存储结构、树的遍历方法、树和森林与二叉树之间的转换以及树的应用等内容。
重点提示:●树的存储结构●树的遍历●树和森林与二叉树之间的转换7-1 重点难点指导7-1-1 相关术语1.树的定义:树是n(n>=0)个结点的有限集T,T为空时称为空树,否则它满足如下两个条件:①有且仅有一个特定的称为根的结点;②其余的结点可分为m(m>=0)个互不相交的子集T1,T2,…,T m,其中每个子集本身又是一棵树,并称为根的子树。
要点:树是一种递归的数据结构。
2.结点的度:一个结点拥有的子树数称为该结点的度。
3.树的度:一棵树的度指该树中结点的最大度数。
如图7-1所示的树为3度树。
4.分支结点:度大于0的结点为分支结点或非终端结点。
如结点a、b、c、d。
5.叶子结点:度为0的结点为叶子结点或终端结点。
如e、f、g、h、i。
6.结点的层数:树是一种层次结构,根结点为第一层,根结点的孩子结点为第二层,…依次类推,可得到每一结点的层次。
7.兄弟结点:具有同一父亲的结点为兄弟结点。
如b、c、d;e、f;h、i。
8.树的深度:树中结点的最大层数称为树的深度或高度。
9.有序树:若将树中每个结点的子树看成从左到右有次序的(即不能互换),则称该树为有序树,否则称为无序树。
10.森林:是m棵互不相交的树的集合。
7-1-2 树的存储结构1.双亲链表表示法以图7-1所示的树为例。
(1)存储思想:因为树中每个元素的双亲是惟一的,因此对每个元素,将其值和一个指向双亲的指针parent构成一个元素的结点,再将这些结点存储在向量中。
(2)存储示意图:-1 data:parent:(3)注意: Parrent域存储其双亲结点的存储下标,而不是存放结点值。
下面的存储是不正确的:-1 data:parent:2.孩子链表表示法(1)存储思想:将每个数据元素的孩子拉成一个链表,链表的头指针与该元素的值存储为一个结点,树中各结点顺序存储起来,一般根结点的存储号为0。
树与二叉树的关系

将一棵树转换为二叉树的方法: ⑴ 树中所有相邻兄弟之间加一条连线。 ⑵ 对树中的每个结点,只保留其与第一个 孩子结点之间的连线,删去其与其它孩子结 点之间的连线。 ⑶ 以树的根结点为轴心,将整棵树顺时针 旋转一定的角度,使之结构层次分明。
树转换为二叉树示意图
A
A
B
E
CF G
DH
I
A
B
E
CF G
DH
I
J
J
A
BC D EG FH I J
用递归的方法描述其转换
若B是一棵二叉树,T是B的根结点,L是B的 左子树,R为B的右子树,设B对应的森林F(B) 中含有的n棵树为T1,T2, …,Tn,则有: (1)B为空,则:F(B)为空的森林(n=0)。
(2)B非空,则:
树
森林
二叉树
先根遍历 先序遍历 先序遍历
后根遍历 中序遍历 中序遍历
3、森林的后序遍历*
若森林非空,则遍历方法为:
(1)后序遍历森林中第一棵树的根结点的子 树森林。 (2)后序遍历除去第一棵树之后剩余的树构 成的森林。 (3)访问第一棵树的根结点。
6.5 哈夫曼树及其应用
6.5.1 哈夫曼树
哈夫曼树最典型、最广泛的应用是在 编码技术上,利用哈夫曼树,可以得到 平均长度最短的编码。这在通讯领域是 极其有价值的。
权值 双亲序号 左孩子序号 右孩子序号
静态三叉链表结构定义
#define N 20 #define M 2*N-1 typedef struct { int weight ;
int parent,Lchild,Rchild ; }HTNode, HuffmanTree[M+1];
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
A
C D H I J
(b)转成二叉树
K
图6-15树转换成二叉树
2016/12/31 14
3.森林转换成二叉树 树和森林都可转换成二叉树,但树转换成二叉树后根结点无右分 支,而森林转换后的二叉树,其根结点有右分支。 将森林转化为二叉树方法如下: (1) 将森林中的每一棵树转换成等价的二叉树。 (2) 保留第一棵二叉树,自第二棵二叉树始,依次将后一棵二叉 树的根结点作为前一棵二叉树根结点的右孩子,当所有的二叉树 依此相连后,所得到的二叉树就是由森林转化成的二叉树。 (3) 以树根为轴心,将整棵树按顺时钟方向旋转约45°。 转换过程如图图6-16 。
• 2.由后序和中序遍历的序列构造二叉树
2016/12/31
6.4
树、森林与二叉树的转换1源自树与二叉树的对应关系树与二叉树均可用二叉链表作为存储结构,因此给定一棵树, 用二叉链表存储,可唯一对应一棵二叉树,反之亦然。
2.树转换成二叉树
将一棵树转化为等价的二叉树方法如下: (1) 在树中各兄弟(堂兄弟除外)之间加一根连线。
/* 二叉树非空 */
/* 访问根结点 */ /* 遍历左子树(递归调用) */ /* 遍历右子树(递归调用) */
中序遍历二叉树的递归算法 void Inorder(bitree root) /* root为根结点,visit()为访问结点的函数 */
{ if ( root !=0)
{ Inorder(root->lchild); visit(root->data); Inorder(root->rchild); } }
//辅助队列 /* P指向根结点 */ /* 初始化队列 */ /* 根结点入队 */ /* 队列Q不空时继续 */ /* 出队,队头元素=>P */ /* 访问结点数据 */ /* 左孩子入队 */ /* 右孩子入队 */
二、二叉树的建立算法(实验需掌握)
• • • 按扩展的先序序列建立二叉树的算法 要求输入时表示出叶子结点。 如图所示:
遍历算法的应用
在遍历算法的基础上完成以下算法:
1.统计二叉树中的叶子结点个数
2.求二叉树的深度
3.统计二叉树中的结点总数
• • • • • • • • • • • •
//统计二叉树深度的算法 int deepth(tnode *root) { int lh,rh; if (root) //二叉树非空 { lh=deepth(root->lchild); rh= deepth(root->rchild); return (lh>rh? lh: rh)+1; } else return 0; } }
• • • • • • • •
2016/12/31
20
• 4.画出以下森林对应的二叉树
A B D G E C F A B D
C
E
F
G
H
H
2016/12/31
21
//统计左子树深度 //统计右子树深度 //最大深度+1
三、构造二叉树
• 给定二叉树的一种遍历结果是无法确定二叉树的; • 恢复二叉树指:根据给定的两种遍历结果,反推出该 二叉树。 • 给定2 种遍历结果(中序、先序;或中序、后序)可唯 一确定一棵二叉树; 注意:必须包括中序遍历。
练习:
• 1.由前序和中序遍历的序列构造二叉树
本课内容
1.遍历二叉树的算法(复习)
2016/12/31
1
遍历二叉树的递归算法
算法6.1 void preorder(bitree root) /* root为根结点,visit()为访问结点的函数 */ 前序遍历二叉树的递归算法
{ if ( root !=0)
{ visit(root->data); preorder(root->lchild); preorder(root->rchild); } }
}
实际上,结点的访问次序就是其进入队列的次序。
二叉树层次遍历的算法(应用辅助队列) void BTlayer( bitree root) { linkqueue Q; bitree P=root; Init_queue(Q); if (root) In_queue(Q,root); while ( Q.front) { P=dele_queue(Q); printf(“%c”,P->data); if (P->lchild) In_queue(Q,P->lchild); if (P->rchild) In_queue(Q,P->rchild); } }
(2) 对于任一结点,只保留它与最左孩子的连线,删去它与其余 孩子之间的连线。
(3) 以树根为轴心,将整棵树按顺时钟方向旋转约45°。
特点:根结点无右子树
2016/12/31 13
A B E F C G I (a) 树 D H J 添加与 删除分支 K E B F
A B C G I D H J 旋转 K E F G
18
2016/12/31
A
A C B
B
D
D E F G
C
E
F G
2016/12/31
19
练习
• 1. 已知一棵二叉树的先序序列为E B A D C F H G I K J,中序序列为A B C D E F G H I J K,请画出该二叉树,并写出后序遍历的结果。
2. 已知二叉树有50个叶子结点,则该二叉树的总结点数至少应有多少个? 3. 给出满足下列条件的二叉树: (1)前序遍历和中序遍历相同; (2)中序遍历和后序遍历相同; (3)前序遍历和后序遍历相同。 4. 画出与下列已知序列对应的树T: 树的先根次序访问序列为GFKDAIEBCHJ; 树的后根次序访问序列为DIAEKFCJHBG。
A B C D F H I T1 A T2 E F C D J H T3 G
E
G
B
I
J
2016/12/31
17
6.4.3 树与森林的遍历
• • • • • • • • • • • 1. 树的遍历 按访问根结点和访问子树的次序不同,可以定义以下所述两种遍历方法: (1)先根遍历(或先序遍历) 若树非空,则遍历过程为: 第一步:访问根结点; 第二步:从左到右,依次先根遍历根结点的每一棵子树。 (2)后根遍历(或后序遍历) 若树非空,则遍历过程为: 第一步:从左到右,依次后根遍历根的每一棵子树; 第二步:访问根结点。 对照转换后所得二叉树可以发现:树的先根遍历与其转换后所得的二叉 树的先根遍历结果一样,而树的后根遍历则对应该二叉树的中序遍历。 所以,可以用二叉树的遍历算法解决树的遍历问题。
/* 二叉树非空 */
/* 遍历左子树(递归调用) */ /* 访问根结点 */ /* 遍历右子树(递归调用) */
后序遍历二叉树的递归算法 void PostOrder(bitree root) /* root为根结点,visit()为访问结点的函数 */ { if ( root !=0) { PostOrder(root->lchild); PostOrder(root->rchild); visit(root->data); } /* 遍历左子树(递归调用) */ /* 遍历右子树(递归调用) */ /* 访问根结点 */ /* 二叉树非空 */
2016/12/31
15
A B C G H I D
E F 转换 B
A C G H I D
E F 二叉树 B C
A E F D H I G
(a) 森林
(b)转换
(c)二叉树
图6-16 森林和对应的二叉树
2016/12/31
16
4.二叉树转换成森林 将当前根结点和其左子树作为森林的一棵树,并将其右子树作为 森林的其他子树; 重复上面直到某结点的右子树为空。
D B E G L H A C
F
• • •
输入序列为: ABD#GL###E##CFH##K### 其中的 # 表示空
K
算法6.4 按扩展先序序列建立二叉树的算法
• • • • • • • • • • • • • • • • typedef char elemtype ; /* 结点数据为char型 */ bitree creatbit() /* 按输入的前序序列建立二叉树,输入以回车表示结束 */ /* 若创建成功,返回该二叉树的根,否则返回空指针 */ { char ch; bitree T; scanf(“%c”,&ch); if (ch==’#’) return (0); /* 返回空二叉树 */ else { T=(bitree)malloc(sizeof(bnode)); /* 生成“根”结点 */ T->data=ch; T->lchild=creatbit(); /* 创建左子树 */ T->rchild=creatbit(); /* 创建右子树 */ return (T); /* 返回根 */ } }
}
4.
二叉树的层次遍历
二叉树的层次遍历:即按照“从上到下,从左至右”的次序访问所有结点 一次且仅一次。对一棵非空的二叉树,先访问根结点,再依次访问左孩子、 右孩子,并记录该层结点的访问次序;依次访问各结点的左孩子和右孩子, 直到访问到最右端的叶子结点。 层次遍历存在容易理解的非递归算法。这里有一个“依序访问下层结点” 的问题,为了记录上一层结点的访问次序,需要使用队列。算法描述如下: 1)初始化队列Q; 2)将根结点入队列; 3)当队列Q不空时,重复以下过程: { 对头元素出队列,并访问该结点; 若该结点左孩子非空,访问左孩子并将左孩子入队; 若结点右孩子非空,访问右孩子并将右孩子入队;