1020 Tree Traversals

2023-05-16

Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder and inorder traversal sequences, you are supposed to output the level order traversal sequence of the corresponding binary tree.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤30), the total number of nodes in the binary tree. The second line gives the postorder sequence and the third line gives the inorder sequence. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in one line the level order traversal sequence of the corresponding binary tree. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the end of the line.

Sample Input:

7
2 3 1 5 7 6 4
1 2 3 4 5 6 7

Sample Output:

4 1 6 3 5 7 2

假设二叉树中的所有键都是不同的正整数。给定后序和中序遍历序列,您应该输出相应二叉树的级序遍历序列。(inorder 是中间的意思,inorder sequence中序) 

输入规范:

每个输入文件包含一个测试用例。对于每种情况,第一行给出一个正整数N(≤30),即二叉树中的节点总数。第二行给出了后序序列,第三行给出了中序序列。一行中的所有数字都用空格隔开。

输出规格:

对于每个测试用例,在一行中打印相应二叉树的级别顺序遍历序列。一行中的所有数字必须正好用一个空格分隔,并且在行的末尾不能有多余的空格。

(级别顺序是层序的意思,也就相当于广度优先的顺序,不是前序!)

不太了解树的建议先看看这个

https://blog.csdn.net/ASBSIHD/article/details/130374198?spm=1001.2014.3001.5502

解题过程

#include<iostream>
#include<string>
#include<map>
#include<vector>
#include<queue>
#include<algorithm>

using namespace std;

int n;
int postorder[50];
int inorder[50];

struct Node
{
	int data;
	Node* lchild;
	Node* rchild;//自己调用当前的结构体,目的就是为了继承更多的数据
};

Node* create(int postL, int postR, int inL,int inR)
{
	if (postL > postR)
	{
		return NULL;
	}

	Node* root = new Node;
	root->data = postorder[postR];

	int i;
	for (i = inL; i <= inR; i++)
	{
		if (inorder[i] == postorder[postR])
			break;
	}

	int leftnum = i - inL;

	root->lchild = create(postL, postL + leftnum - 1, inL, i - 1);
	root->rchild = create(postL + leftnum, postR - 1, i + 1, inR);

	
	return root;
}

int num = 0;
void levelorder(Node* root)
{
	queue<Node*>q;
	q.push(root);

	while (!q.empty())
	{
		Node* now = q.front();
		q.pop();
		cout << now->data;
		num++;
		if (num < n)
			cout << " ";
		if (now->lchild != NULL)
			q.push(now->lchild);
		if (now->rchild != NULL)
			q.push(now->rchild);

	}
}


int main()
{
	
	cin >> n;
	for (int i = 0; i < n; i++)
		cin >> postorder[i];
	for (int i = 0; i < n; i++)
		cin >> inorder[i];

	Node* root=create(0, n - 1, 0, n - 1);

	levelorder(root);

	return 0;
}

详解

#include <iostream>
#include <queue>
#include <cstring>
#include <algorithm>

using namespace std;

struct Node {
    int data;//储存数据
    Node* lchild;//child起到连接左/右子树的作用,分别将两边的树都连接起来,是左右树的节点
    Node* rchild;
}node;
//这里可以用这个名字代替Node*,就跟java的效果一样
//作为一个node类型

const int maxn = 50;

int postorder[maxn], inorder[maxn];
int n; //!!!

//本质上就是自己理解如何通过后序中序来确定树的结构
//后序确定根,中序确定左右孩子,可以先自己手画出树的结构
//清晰逻辑后再通过代码实现
 //总的核心就是参照视频中的理解,如何构造树,然后使用DFS和指针连接起来即可
// 根据树的构造编写代码

//中序分化左右子树,后序确定根节点

//当我们将它看作为根的时候存放数据,看作为左右孩子的时候起到连接各个节点的作用
//目的就是为了输出,即输出根节点内容后往下面的孩子找,然后继续输出。


//          后序最左边开始 最右边      中序  左边   右边           ,此处都表示左右边界
Node* create(int postL, int postR, int inL, int inR) //创造一棵树
{
    if (postL > postR) //当前根节点已经没有对应的孩子时,即左/右节点已经没有时
    {
        return NULL; 
    }
   
    //寻找并插入节点

    Node* root = new Node;  //!!!没初始化
    //每次都新建一个Node储存数据
    //最后return到一个root中,就将他们连接起来了

    root->data = postorder[postR];   //通过后序规律,找到根节点    

    int i;//表示当前根节点的位置
    for (i = inL; i <= inR; i++) {//寻找根节点在中序的位置,从而寻找左孩子/右孩子
        if (inorder[i] == postorder[postR]) {//!!!!
            break;
        }
    }


    int leftNum = i - inL;//当前根节点的左边节点的个数

    
   
    
 //选定节点范围
    //优先寻找左子树,然后找右
    //注意这些减和加都是相当于往左/右移动,来确定左/右子树的节点范围
//一直都在寻找的是下标


                         //后序新树根节点选定范围       中序左/右子节点范围
    root->lchild = create(postL, postL + leftNum - 1, inL, i - 1);  //左子树
    //postL + leftNum - 1,因为左右根,上面求出左边节点的个数,那我们只要确定规则和个数
    // 就能锁定后序中的所求根节点的范围在哪,-1是因为下标从0开始
    // 
    // 左边的所有节点都可能为根节点,需要下一次进一步判断.
    
    //注意,位置都是在对应的树下的下标
    
    //i-1表示根节点左边,在中序中左边都是作为当前根的孩子
   


    //右子树,一旦没了左孩子,就去找当前节点的右孩子(符合左根右原则)
    root->rchild = create(postL + leftNum, postR - 1, i + 1, inR);
    //中序开始向右边遍历
    //与左子树类似.
    //postR-1就是沿着当前当前根节点找右孩子,此时根的左孩子没有,只有右孩子,
    //右孩子仍然存在,所以下一个节点仍然是作为新树的根,后序顺序左右根,所以当前根的左边一位就是新树的根节点
    //i+1是往右边找,因为此时根节点没有了左孩子,左根右,所以此时在中序中的节点范围只能是在根节点的右边,所以加一

 /*   postL + leftNum - 1与postR - 1有什么不同?*/
    //目标是不同的,前面是一直在找左子树,而后面是转向为右子树,找的都是右节点的范围,是不一样的
    //postR是范围右侧的边界,在后序中是根,去掉当前根就减一即可
    
    //如postL + leftNum就是当前左边界加上左子树节点的个数,就相当于排除了左节点,只选择右节点
    //因为后序是左右根,所以直接加就能移动到右节点

    //inL和inR意思就是继承上一个树的结果,不做任何变化,也就是不动,包括postR等也都是,使用的时候都是继承的
    //都是上一次的结果,直接拿来用就行了.


    


    return root;    //返回节点,将所有的节点连接起来
}

//层次遍历
int num = 0;    //!!!已经输出的节点个数
void levelorder(Node* root) //BFS
//root只能上传开头的节点,也就是头节点,然后输出,但是头结点的孩子就是lchild与rchild
//now节点就是接收了root的内容,然后孩子再往下遍历
{
    queue<Node*> q;
    q.push(root);

    while (!q.empty()) {
        Node* now = q.front();
        q.pop();    //弹出
        printf("%d", now->data);
        num++;
        if (num < n) cout << " ";
        if (now->lchild != NULL) {//从左到右插入队列,然后循环输出
            q.push(now->lchild);//now指针变更指向孩子,也就是更新节点信息,往下遍历
        }
        if (now->rchild != NULL) {
            q.push(now->rchild);
        }
    }
}

int main()
{

    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> postorder[i];
    }
    for (int i = 0; i < n; i++) {
        cin >> inorder[i];
    }


    Node* root1 = create(0, n - 1, 0, n - 1);   //!!!

    levelorder(root1);
    return 0;
}

//反思,写程序如果没有特殊情况,那么只用把一个步骤想清楚写好就可以了
//剩下的重复操作交给递归,循环,不用理解的太透彻,交给计算机计算就行了

  

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

1020 Tree Traversals 的相关文章

  • 从整数流创建平衡二叉搜索树

    我刚刚结束了一次工作面试 我一直在纠结这个问题 在我看来 在 15 分钟的面试中这是一个很难回答的问题 问题是 编写一个函数 给定整数流 无序 构建平衡搜索树 现在 您不能等待输入结束 它是一个流 因此您需要动态平衡树 我的第一个答案是使用
  • D3.js 在径向树中的元素之间添加链接(分层边缘捆绑元素)

    几个月前 我尝试过使用 d3 js 将分层边缘捆绑和径向 Reingold Tilford 树结合起来 https stackoverflow com questions 39150514 d3 js combining hierarchi
  • cytoscape:改变第二轴出租车分支的长度

    I want to create a tree with different branch lengths looking like this Is there a possibility of assigning a length to
  • 在Python中生成字典树中的所有叶到根路径

    我有一个 非标准 形式的字典树 如下所示 tree 0 A B C D E F 叶节点被定义为字典键值对 其中值是空字典 我想将所有叶到根路径提取为列表列表 如下所示 paths C B A 0 E D 0 F D 0 如果有帮助的话 也可
  • 从物化路径构建 JSON 树

    我计划在 MongoDB 中使用物化路径来表示树 并且需要将物化路径转换回 JSON 树 前任 物化路径 var input id 0 path javascript id 1 path javascript database id 2 p
  • 使用confusioMatrix时如何解决“数据不能有比参考更多的级别”错误?

    我正在使用 R 编程 我将数据分为训练数据和测试数据以预测准确性 这是我的代码 library tree credit lt read csv C Users Administrator Desktop german credit 2 cs
  • 如何在 R 中将树转换为树状图?

    如何将树 Java 程序的输出 转换为 R 中的树状图 目前 我正在使用给出的建议将树转换为 Newick 格式here https stackoverflow com questions 2612579 converting a tree
  • Java 中的树实现

    我得到了以下树 然后我们被告知使用last child previous sibling方法来改变这三个的实现 结果如下 我现在正在研究 Java 实现 以在这棵树上执行不同的功能 我们有一个 Tree 接口和一个 TreeNode 接口
  • 使用树输出预测 Spark 中梯度提升树情况下的类概率

    众所周知 Spark 中的 GBT 目前可以为您提供预测标签 我正在考虑尝试计算一个类的预测概率 假设所有实例都落在某个叶子下 构建 GBT 的代码 import org apache spark SparkContext import o
  • 如何在 Clojure 中遍历一棵树,同时收集每个节点节点的值?

    我想创建一个函数来收集二叉树中每个节点的值 在 ClojureDocs 中 我发现了几个用于遍历树 图的函数 例如 tree seq prewalk 和 postwalk https clojuredocs org clojure core
  • Visual Studio代码侧边栏垂直引导线(自定义侧边栏)

    有人知道 Visual Studio 代码的扩展可以像 netbeans 一样在侧边栏 用于文件和文件夹 上显示垂直指南吗 或者vscode中有一些设置吗 Netbeans 快照 https i stack imgur com CFJsw
  • 如何递归探索Python嵌套字典? [复制]

    这个问题在这里已经有答案了 我很好奇是否有一种方法可以在 python 中递归地探索嵌套字典 我的意思是 假设我们有一个如下示例 d a b c 1 2 3 获取最里面字典的内容需要什么代码 c 1 2 3 遍历a and b 在这种情况下
  • 命令提示符中树的输出

    我希望能够使用 tree F A gt desktop file txt 命令仅输出文本文件 目前 它输出每个文件扩展名 有谁知道有一个简单的方法可以做到这一点 Tree仅接受几个命令行参数 c gt Tree Graphically di
  • 为什么在算法中使用子树大小来选择二叉树中的随机节点?

    我偶然发现了从二叉树中选择随机节点的算法的几种实现 它们都使用子树大小属性 但是 我不明白为什么知道子树大小有帮助 这是实现A https stackoverflow com a 32011526 and B https www geeks
  • Tic-Tac-Toe AI:如何制作树?

    在制作井字游戏机器人时 我在尝试理解 树 时遇到了巨大的障碍 我理解这个概念 但我不知道如何实现它们 有人可以向我展示一个如何为这种情况生成树的示例吗 或者关于生成树的好教程 我想最困难的部分是生成部分树 我知道如何实现生成整棵树 但不知道
  • Java hibernate/jpa 如何创建自相关的动态通用实体

    我想使用 JPA hibernate 创建动态和通用的超类 它将针对每个层次结构模型进行扩展 例如 角色 页面 目录 部门 权限 树 我想使用递归和java反射来创建这个对象动态树 它应该看起来像这样 该实体应该引用自身实体 我希望它是完全
  • 使用霍夫曼代码压缩文件的步骤

    我知道有很多涉及霍夫曼代码的问题 包括我自己的另一个问题 但我想知道实际编码文本文件的最佳方法是什么 减压看似微不足道 遍历树 在 0 处向左 在 1 处向右 打印字符 但是 如何进行压缩呢 以某种方式将字符的位表示存储在树的节点中 每次遇
  • 在 Python 中删除表达式树及其每个子表达式树中第一个元素周围的括号

    目标是实现简化操作 删除表达式树及其每个子表达式树中第一个元素周围的括号 其中表达式作为括在各个括号中的字符串输入给出 这必须适用于任意数量的括号 例如 12 3 45 6 gt 123 45 6 删除 12 周围的括号 然后删除 45 周
  • 任何人都知道 JQuery 插件可以生成类似于 geni.com 上的树形菜单

    大家好 我花了几个小时寻找一个 Jquery 插件来生成像 geni com 上那样的树形菜单模块 如果有人知道 Jquery 中的这样的插件或脚本 请让我知道或指导我如何使用 Jquery 开发这样的功能 请检查我正在寻找什么http w
  • 使用 Java 进行树可视化 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个库来生成图形或树 例如组织图表 该库应该能够从该图中生成纯图像 有谁知道一个好的 希望开源

随机推荐

  • Android问题集锦之八:调用其他程序中的activity和Permission Denial: starting Intent 错误解决办法

    今天想调试多个task中栈的情况 xff0c 在测试程序中调用另一个程序的activity xff0c 代码片段如下 xff1a btnStartX 61 Button findViewById R id btnStartX btnStar
  • VB.NET串口通信例子--我的回忆录

    这是我3年前的一个例子 xff0c 最近翻出来回忆一下 串口是计算机上一种非常通用设备通信的协议 大多数计算机包含两个基于RS232的串口 xff0c 现在配电脑好像只有一个 串口同时也是仪器仪表设备通用的通信协议 xff1b 很多GPIB
  • TensorFlowLite GPU加速

    官方文档 https tensorflow google cn lite performance gpu hl 61 zh cn TF LITE支持移动端GPU加速 xff0c 特别对android端的支持比较丰富 相对android来说
  • C语言基础----流程控制

    流程控制是C语言中比较基础的 它分为三种状态 xff1a 1是顺序结构 2是选择结构 3是循环结构 我要说明后两种结构 xff0c 选择机构和循环结构 首先先说 xff1a 选择结构 选择结构是指 xff1a 当一个条件成立则执 xff08
  • 复杂数据类型——数组

    复杂数据类型是C语言基础的重点 1 数组 xff1a 存储一组数据 2 特点 xff1a 只能存放一种类型的数据 如int类型 xff0c float类型的数据 数组的元素个数只可以放常量 int ages 5 61 1 2 3 格式 xf
  • OC语言——基本语法和思想

    今天学习了OC语言基础语法 1 oc语言完全兼容C语言 xff0c 后缀为 m类型 被广泛应运与开发苹果mac os x平台和ios开发平台 2 oc语言关键字基本上以 64 开头 xff0c oc字符串也是以 64 开头 3 基本类型新加
  • OC语言——三大特性-继承与多态

    继承是oc中比较常见的 1 继承 xff1a 就是当两个类拥有相同的属性和方法时 xff0c 就可以将相同的东西抽取到一个父类中 子类可以拥有父类中所有的成员变量和方法 2 继承的好处 xff1a 可以抽取重复代码 xff0c 节省时间 建
  • OC语言——点语法和成员变量的4种作用域及property和synthesize的使用

    点语法 xff1a 点语法的本质还是方法调用 Person p 61 Person new 点语法的本质还是方法调用 p age 61 10 p setAge 10 一 点语法注意点 xff1a 64 implementation Pers
  • 树排序的理解

    参考文献与详细资料 xff1a https blog csdn net weixin 64067830 article details 124443430 视频 https www bilibili com video BV1iU4y1B7
  • OC语言——构造方法和分类的使用

    一 构造方法 1调用 43 alloc分配存储空间 Person p 61 Person alloc 2初始化 init Person p1 61 p init 可以整合为一句 Person p2 61 Person alloc init
  • 使用CSDN-markdown

    欢迎使用Markdown编辑器写博客 本Markdown编辑器使用StackEdit修改而来 xff0c 用它写博客 xff0c 将会带来全新的体验哦 xff1a Markdown和扩展Markdown简洁的语法代码块高亮图片链接和图片上传
  • 【笔试&面试】关于动态链接库

    动态链接库英文为DLL xff0c 是Dynamic Link Library 的缩写形式 xff0c DLL 是一个包含可由多个程序同时使用的代码和数据的库 xff0c DLL 不是可执行文件 动态链接提供了一种方法 xff0c 使进程可
  • 虚函数表的实现细节

    1 虚函数 虚表是怎么实现的 xff1f 虚表存放在哪里 xff1f 虚表中的数据是在什么时候确定的 xff1f 对象中的虚表指针又在什么时候赋值的 xff1f 我们很难通过 C 43 43 语言本身来找到答案 C 43 43 标准给编译器
  • 三种工厂模式区别总结

    工厂模式分为三种 xff1a 简单工厂 工厂模式和抽象工厂模式 三者之间存在哪些异同呢 xff1f 先分别看看各个模式的特点 一 简单工厂模式 xff1a 实现了算法和界面的分离 xff0c 也就是将业务逻辑和界面逻辑分开了 xff0c 降
  • 快速排序 改进快排的方法

    快速排序法事应用最广泛的排序算法之一 xff0c 最佳情况下时间复杂度是 O nlogn 但是 最坏情况下可能达到 O n 2 说明快速排序达到最坏情况的原因 并提出改善方案并实现 之 答 xff1a 改进方案 xff1a 改进选取枢轴的方
  • linux select函数详解

    在 Linux 中 xff0c 我们可以使用 select 函数实现 I O 端口的复用 xff0c 传递给 select 函数的参数会告诉内核 xff1a 我们所关心的文件描述符 对每个描述符 xff0c 我们所关心的状态 我们是要想从一
  • Linux epoll详解

    Linux epoll详解 一 什么是epoll epoll是什么 xff1f 按照man手册的说法 xff1a 是为处理大批量句柄而作了改进的poll 当然 xff0c 这不是2 6内核才有的 xff0c 它是在2 5 44内核中被引进的
  • 转折后的总结--2014年找工作

    转折后的总结 找工作 好吧 xff0c 还是忍不住做个总结 xff0c 毕竟还是我人生中一次比较大的事件了 非常感谢华科 xff0c 我的第二个母校能提供给我一个优秀的平台 非常感谢信息安全与保密实验室607室的老师们 xff0c 给我诸多
  • 2014找工作总结-机会往往留给有准备的人

    好基友的文章必须转 xff0c 大神一枚 xff1a 出处 xff1a http blog csdn net xiajun07061225 article details 12844801 其实我的求职过程在十一之前就已经结束了 xff0c
  • 1020 Tree Traversals

    Suppose that all the keys in a binary tree are distinct positive integers Given the postorder and inorder traversal sequ