二叉树是树结构中的重要概念,一些特殊的二叉树如满二叉树和完全二叉树由于节点序号的特殊关系,在一些算法中十分常见。

这篇文章将从三个方面介绍有关二叉树的知识点:

(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-应用二叉树的基本概念编程的更多相关文章

  1. 数据结构编程实验——chapter8-采用树结构的非线性表编程

    关于树结构的非线性表编程在数据结构中可以说占据了半壁江山,其中涉及的知识点繁杂,但也是数据结构体现运算优化的核心所在,下面我们将较为初步且系统得讨论数据结构中一系列有关树的表示. 首先我们再次明确树的 ...

  2. 20172301 《Java软件结构与数据结构》实验二报告

    20172301 <Java软件结构与数据结构>实验二报告 课程:<Java软件结构与数据结构> 班级: 1723 姓名: 郭恺 学号:20172301 实验教师:王志强老师 ...

  3. 2017-2018-2 1723《程序设计与数据结构》实验四 & 实验五 & 课程总结 总结

    作业地址 实验四作业:https://edu.cnblogs.com/campus/besti/CS-IMIS-1723/homework/1943 提交情况如图: 实验五作业:https://edu ...

  4. 20172301 《Java软件结构与数据结构》实验三报告

    20172301 <Java软件结构与数据结构>实验三报告 课程:<Java软件结构与数据结构> 班级: 1723 姓名: 郭恺 学号:20172301 实验教师:王志强老师 ...

  5. 20172329 2018-2019 《Java软件结构与数据结构》实验三报告

    20172329 2018-2019-2 <Java软件结构与数据结构>实验三报告 课程:<Java软件结构与数据结构> 班级: 1723 姓名: 王文彬 学号:2017232 ...

  6. 20172329 2018-2019-2 《Java软件结构与数据结构》实验二报告

    20172329 2018-2019-2 <Java软件结构与数据结构>实验二报告 课程:<Java软件结构与数据结构> 班级: 1723 姓名: 王文彬 学号:2017232 ...

  7. 20172328《程序设计与数据结构》实验四 Android程序设计报告

    20172328<程序设计与数据结构>实验四 Android程序设计报告 课程:<程序设计与数据结构> 班级: 1723 姓名: 李馨雨 学号:20172328 实验教师:王志 ...

  8. 20172328《程序设计与数据结构》实验三 敏捷开发与XP实践报告

    20172328<程序设计与数据结构>实验三 敏捷开发与XP实践报告 课程:<程序设计与数据结构> 班级: 1723 姓名: 李馨雨 学号:20172328 实验教师:王志强 ...

  9. 20172310 2017-2018-2 《程序设计与数据结构》实验三报告(敏捷开发与XP实践)

    20172310 2017-2018-2 <程序设计与数据结构>实验三报告(敏捷开发与XP实践) 课程:<程序设计与数据结构> 班级: 1723 姓名: 仇夏 学号:20172 ...

随机推荐

  1. Scrum Meeting Beta - 9

    Scrum Meeting Beta - 9 NewTeam 2017/12/8 地点:新主楼F座二楼 任务反馈 团队成员 完成任务 计划任务 安万贺 解决离线状态下启动时报错的问题Issue #15 ...

  2. gitlab账号注册及分组

    .开启注册邮箱验证 admin area -->setting-->Sign-up restrictions-->勾选Send confirmation email on sign- ...

  3. go 面试题总结

    1.什么是goroutine,他与process, thread有什么区别? 2. 什么是channel,为什么它可以做到线程安全? 3. 了解读写锁吗,原理是什么样的,为什么可以做到? 4. 如何用 ...

  4. [Oracle] 11.2.0.1 的客户端无法连接12.2.0.1 的DB端 28040

    最近有一个应用服务器安装上了 11.2.0.1 的oracle DB端 又想当 客户端用来 注册 oracle12.2.0.1的DB端发现不行 但是很奇怪 报的错误竟然是 ora 01017 密码错误 ...

  5. php反射方法信息

    <?phpclass ReflectionFunction implements Reflector{    final private __clone()    public object _ ...

  6. Pscp与服务器文件传递

    1. 下载pscp.exe https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html 选择并下载pscp.exe 2. 执行cmd程 ...

  7. 每日一问(常用的集合接口和类有哪些【二】)—ArrayList类和数组之间的转换

    ArrayList的实质是数组,但是在类的实例中所存储的数组是无法访问的,因此实际上是无法直接作为数组使用,那么如何将这两者进行转化呢? Collection接口定义了toArray的方法,可将实现该 ...

  8. BZOJ3142 HNOI2013数列(组合数学)

    考虑差分序列.每个差分序列的贡献是n-差分序列的和,即枚举首项.将式子拆开即可得到n*mk-1-Σi*cnt(i),cnt(i)为i在所有差分序列中的出现次数之和.显然每一个数出现次数是相同的,所以c ...

  9. Day 5 笔记 dp动态规划

    Day 5 笔记 dp动态规划 一.动态规划的基本思路 就是用一些子状态来算出全局状态. 特点: 无后效性--狗熊掰棒子,所以滚动什么的最好了 可以分解性--每个大的状态可以分解成较小的步骤完成 dp ...

  10. P2219 [HAOI2007]修筑绿化带

    我是题面 这道题跟理想的正方形很像,不大明白蛤OI是怎么想的,一年出两道这么相近的题 这道题有两个矩形,所以就有了两种做法(说是两种做法,其实只是维护的矩形不同) 一种是维护大矩形,一种是维护小矩形, ...