数据结构编程实验——chapter9-应用二叉树的基本概念编程
二叉树是树结构中的重要概念,一些特殊的二叉树如满二叉树和完全二叉树由于节点序号的特殊关系,在一些算法中十分常见。
这篇文章将从三个方面介绍有关二叉树的知识点:
(1) 普通有序树转化为二叉树。
(2) 计算二叉树路径。
(3) 通过两种遍历确定二叉树结构。
一.普通有序树转化为二叉树
其实不仅限于有序树,森林转化成二叉树也是利用了这里给出的方法。
左子女-右兄弟法:
1) T中节点与T’中一一对应,即T中每一个节点的序号的值在T’中保持不变。
2) T中某节点v的第一个儿子节点为v1,则在T’中v1为对应节点v的左儿子。
3) T中节点v的儿子序列(即v1节点的兄弟序列),在T’中依次链接成一条开始与v1的右链。
Ex1(poj3437):
用du字符串的形式(d是down的缩写,u是up的缩写,该字符串描述了先序遍历有序树的方向变化,间接描述的树结构)表征,现在要求我们求解有序树的高度及其转化成二叉树后的高度。
首先我们明确一个知识点,根据普通有序树转化成二叉树的方法,我们可以得到这样一个公式:对于节点x及其在有序树中的父节点y,我们设level(i)代表节点i在二叉树中的层次(根节点是第0层),那么有level(x) = level(y) + son_th.其中son_th表示x是y的第几个儿子。因此我们在算法设计中,首先递归设计算法统计有序树的层数,中间设置变量tempson来记录当前节点是其有序树中的父节点中的第几个儿子,顺便就可以求出二叉树的层次。
代码如下:
#include<cstdio>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
string s;
int i , n = , height1 , height2;
void work(int level1 , int level2){//递归计算树高,每次函数调用表示我们在两种树种遍历到同一节点,这一节点在有序树和二叉树中的层次分别是level1 , level2
int tempson = ;//该节点的儿子序列计数器置零
while(s[i] == 'd'){//如果当前方向向下,说明有儿子
i++;
tempson++;
work(level1 + , level2 + tempson);//基于儿子节点递归调用函数
}
//完成了该节点所有子节点的递归函数调用,维护层数最大值
height1 = max(height1 , level1);
height2 = max(height2 , level2);
i++;
}
int main(){
while(cin >> s && s != "#"){
i = height1 = height2 = ;
work( , );
cout << "Tree "<<++n<<":"<<height1 <<" => "<<height2<<endl;
}
}
二.计算二叉树的路径
在一些题目中往往要求我们在二叉树中的某条路径上行遍以获得一些信息。完全二叉树就是一种非常利于我们行遍路径的结构。设我们有n节点的完全二叉树,且姐弟拿笔拿好是从上而下从左而右递增分布的,则任意分支节点i的父节点是floor((i-1)/2);若节点i有左儿子则左儿子的节点序号是2i+1,若节点i有右儿子,则节点序号为2i+2.
Ex1:
假设我们有一个二叉树,根节点标识为(1,1),其左儿子被标识为(2 , 1),右节点被标识为(1,2)。抽象得说,若一个节点的标识为(a , b),则其左儿子的标识为(a + b , b),右儿子标识为(a , a+b).那么现在给出一个节点的标识(a , b),编程计算这个这个节点相对于根节点(1 ,1)向左移动了多少步,向右移动了多少步。
这里实际上就是给出了一种二叉树路径的一种生成机制。我们从已知标识的(a,b)开始分析。如果a>b,则显然一定是之前的某些节点向左移动了若干步,朴素来讲,我们基于(a,b),其父节点是(a – b , b),如果依然满足a-b > n,那么在走到其父节点(a – b – b ,b)。这一迭代扩成可以概括为:
If(a > b){
up = floor((a – 1 )/b).某个节点连续往左儿子走up步走到(a,b)
left += up;//更新
a -= up*b. //此时a一定是b的剩余系。但是a不会等于0,这也是为什么用(a-1)/b而不用a/b的原因。
}
对称的,b>a的情形也是一样,经过多次迭代运算,知道a = b = 1,说明路径已经行遍到了根节点。
参考代码如下:
#include<cstdio>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
string s;
int i , n = , height1 , height2;
void work(int level1 , int level2){//递归计算树高,每次函数调用表示我们在两种树种遍历到同一节点,这一节点在有序树和二叉树中的层次分别是level1 , level2
int tempson = ;//该节点的儿子序列计数器置零
while(s[i] == 'd'){//如果当前方向向下,说明有儿子
i++;
tempson++;
work(level1 + , level2 + tempson);//基于儿子节点递归调用函数
}
//完成了该节点所有子节点的递归函数调用,维护层数最大值
height1 = max(height1 , level1);
height2 = max(height2 , level2);
i++;
}
int main(){
while(cin >> s && s != "#"){
i = height1 = height2 = ;
work( , );
cout << "Tree "<<++n<<":"<<height1 <<" => "<<height2<<endl;
}
}
数据结构编程实验——chapter9-应用二叉树的基本概念编程的更多相关文章
- 数据结构编程实验——chapter8-采用树结构的非线性表编程
关于树结构的非线性表编程在数据结构中可以说占据了半壁江山,其中涉及的知识点繁杂,但也是数据结构体现运算优化的核心所在,下面我们将较为初步且系统得讨论数据结构中一系列有关树的表示. 首先我们再次明确树的 ...
- 20172301 《Java软件结构与数据结构》实验二报告
20172301 <Java软件结构与数据结构>实验二报告 课程:<Java软件结构与数据结构> 班级: 1723 姓名: 郭恺 学号:20172301 实验教师:王志强老师 ...
- 2017-2018-2 1723《程序设计与数据结构》实验四 & 实验五 & 课程总结 总结
作业地址 实验四作业:https://edu.cnblogs.com/campus/besti/CS-IMIS-1723/homework/1943 提交情况如图: 实验五作业:https://edu ...
- 20172301 《Java软件结构与数据结构》实验三报告
20172301 <Java软件结构与数据结构>实验三报告 课程:<Java软件结构与数据结构> 班级: 1723 姓名: 郭恺 学号:20172301 实验教师:王志强老师 ...
- 20172329 2018-2019 《Java软件结构与数据结构》实验三报告
20172329 2018-2019-2 <Java软件结构与数据结构>实验三报告 课程:<Java软件结构与数据结构> 班级: 1723 姓名: 王文彬 学号:2017232 ...
- 20172329 2018-2019-2 《Java软件结构与数据结构》实验二报告
20172329 2018-2019-2 <Java软件结构与数据结构>实验二报告 课程:<Java软件结构与数据结构> 班级: 1723 姓名: 王文彬 学号:2017232 ...
- 20172328《程序设计与数据结构》实验四 Android程序设计报告
20172328<程序设计与数据结构>实验四 Android程序设计报告 课程:<程序设计与数据结构> 班级: 1723 姓名: 李馨雨 学号:20172328 实验教师:王志 ...
- 20172328《程序设计与数据结构》实验三 敏捷开发与XP实践报告
20172328<程序设计与数据结构>实验三 敏捷开发与XP实践报告 课程:<程序设计与数据结构> 班级: 1723 姓名: 李馨雨 学号:20172328 实验教师:王志强 ...
- 20172310 2017-2018-2 《程序设计与数据结构》实验三报告(敏捷开发与XP实践)
20172310 2017-2018-2 <程序设计与数据结构>实验三报告(敏捷开发与XP实践) 课程:<程序设计与数据结构> 班级: 1723 姓名: 仇夏 学号:20172 ...
随机推荐
- HDU 4123 Bob’s Race 树形dp+单调队列
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4123 Time Limit: 5000/2000 MS (Java/Others) Memory L ...
- “吃神么,买神么”的第一个Sprint计划(第七天)
“吃神么,买神么”项目Sprint计划 ——5.25 星期一(第五天)立会内容与进度 摘要: 所有的部件都完成,在贴每个人负责的部件时发现很多问题,很多网页布局的运用不熟练,一部分的div会跑位置~ ...
- Unity3D游戏开发——访问集中式共享模块的设计模式
什么是设计模式 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类的.代码设计经验的总结.设计模式是开发人员在开发过程中面临的一般问题的解决方案,这些解决方案是众多开发人 ...
- 汇编语言段和RSEG用法
RSEG是段选择指令,要想明白它的意思就要了解段的意思.段是程序代码或数据对象的存储单位.程序代码放到代码段,数据对象放到数据段.段分两种,一是绝对段,一是再定位段.绝对段在汇编语言中指定,在用L51 ...
- sqlserver 修改表字段长度
ALTER TABLE Table1 ALTER COLUMN column1 VARCHAR(255)
- Delphi中使用OLE方法操作Excel
首先创建 Excel 对象,使用ComObj: var ExcelApp: Variant; ExcelApp := CreateOleObject( ′Excel.Application′ ); 注 ...
- Python网络爬虫(1)--url访问及参数设置
环境:Python2.7.9 / Sublime Text 2 / Chrome 1.url访问,直接调用urllib库函数即可 import urllib2 url='http://www.baid ...
- c3p0连接池基本配置mysql和oracle
c3p0-config.xml <?xml version="1.0" encoding="UTF-8"?> <c3p0-config> ...
- mysql实现消息队列
mysql之消息队列 消息队列:在消息的传输过程中保存消息的容器. 消息队列管理器在将消息从它的源中继到它的目标时充当中间人.队列的主要目的是提供路由并保证消息的传递:如果发送消息时接收者不可用, ...
- 【Java并发编程】之六:Runnable和Thread实现多线程的区别
Java中实现多线程有两种方法:继承Thread类.实现Runnable接口,在程序开发中只要是多线程,肯定永远以实现Runnable接口为主,因为实现Runnable接口相比继承Thread类有如下 ...