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

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

(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. 22_IO_第22天(File、递归)_讲义

    今日内容介绍 1.File 2.递归 xmind:下载地址: 链接:https://pan.baidu.com/s/1Eaj9yP5i0x4PiJsZA4StQg 密码:845a 01IO技术概述 * ...

  2. ASP.NET MVC 4.0 参考源码索引

    http://www.projky.com/asp.netmvc/4.0/Microsoft/AspNet/Mvc/Facebook/FacebookAppSettingKeys.cs.htmlhtt ...

  3. C++ 类之间的互相调用

    这几天做C++11的线程池时遇到了一个问题,就是类A想要调用类B的方法,而类B也想调用类A的方法 这里为了简化起见,我用更容易理解的观察者模式向大家展开陈述 观察者模式:在对象之间定义一对多的依赖,这 ...

  4. vue 实战 遇到问题记录

    vue-router  配置路由遇到问题 1.一个 new Router({ routes:[ { path:'/', component:Good    ///不要写成components  否则报 ...

  5. LR_问题_虚拟用户以进程和线程模式运行的区别

    进程方式和线程方式的优缺点: 如果选择按照进程方式运行, 每个用户都将启动一个mmdrv进程,多个mmdrv进程会占用大量内存及其他系统资源,这就限制了可以在任一负载生成器上运行的并发用户数的数量,因 ...

  6. 【转】正确的 Composer 扩展包安装方法

    简单解释 composer install - 如有 composer.lock 文件,直接安装,否则从 composer.json 安装最新扩展包和依赖: composer update - 从 c ...

  7. SPOJ NETADMIN_Smart Network Administrator

    给一个图,某些点需要单独以某一种颜色的线连接到1点,问如何安排能够使得整个图颜色最多的一条路颜色最少. 显然,二分枚举然后加以颜色其实就是流量了,相当于对每条边限定一个当前二分的流量值,判断能否满流即 ...

  8. Codechef_JULY14

    感觉这套比赛题目比较容易,没有以前做过的某次codechef那么凶残.题目还是很有意思的,最好的是有中文翻译. CSUB:签到题,直接从左往右扫一遍即可,维护前面出现过多少个1. #include & ...

  9. spring通过工厂模式解决页面耦合问题

    spring通过工厂模式解决页面耦合问题

  10. [Offer收割]编程练习赛23-freeloop

    A. H国的身份证号码I dfs裸题. 时间复杂度\(O(n^k)\). #include <bits/stdc++.h> #define FOR(i,a,b) for (int i=a; ...