【C++】根据二叉树的前序遍历和中序遍历重建二叉树并输出后续遍历
/*
现在有一个问题,已知二叉树的前序遍历和中序遍历:
PreOrder:GDAFEMHZ
InOrder:ADEFGHMZ
我们如何还原这颗二叉树,并求出他的后序遍历 我们基于一个事实:中序遍历一定是 { 左子树中的节点集合 },root,{ 右子树中的节点集合 },前序遍历的作用就是找到每颗子树的root位置。 算法1
输入:前序遍历,中序遍历
1、寻找树的root,前序遍历的第一节点G就是root。
2、观察前序遍历GDAFEMHZ,知道了G是root,剩下的节点必然在root的左或右子树中的节点。
3、观察中序遍历ADEFGHMZ。其中root节点G左侧的ADEF必然是root的左子树中的节点,G右侧的HMZ必然是root的右子树中的节点,root不在中序遍历的末尾或开始就说明根节点的两颗子树都不为空。
4、观察左子树ADEF,按照前序遍历的顺序来排序为DAFE,因此左子树的根节点为D,并且A是左子树的左子树中的节点,EF是左子树的右子树中的节点。
5、同样的道理,观察右子树节点HMZ,前序为MHZ,因此右子树的根节点为M,左子节点H,右子节点Z。 观察发现,上面的过程是递归的。先找到当前树的根节点,然后划分为左子树,右子树,然后进入左子树重复上面的过程,然后进入右子树重复上面的过程。最后就可以还原一棵树了: PreOrder:GDAFEMHZ
InOrder:ADEFGHMZ
从而得到PostOrder:
AEFDHZMG
*/ #include<iostream>
#include<cstring>
using namespace std;
const int M=;
char pr[M];
char in[M]; struct node
{
char data;
node *l;
node *r;
};
/*
void build(node * & t,int prl,int prr,int inl,int inr)
{
char m=pr[prl];
//printf("%c\n",m);
if(prl>prr||inl>inr)
{
t=NULL;
return ;
}
int i1=0;// -> middle num in the pr
int i2=0;// -> middle num in the in
while(in[i2]!=m)
i2++;
i1=i2;
t=new node();
t->data=m; if(prl==prr||inl==inr)
{
t->l=NULL;
t->r=NULL;
return ;
}
else
{
build(t->l,prl+1,i1,inl,i2-1);//go build left part
build(t->r,i1+1,prr,i2+1,inr);//go build right part
}
}
*/
void create(node * &t, int preL, int preR, int inL,int inR) {
if ( preL > preR )
{
t=NULL;
return ;
}
t = new node();
t->data = pr[preL];
int index;
for ( index = inL; index <= inR; index++ ) {
if ( in[index] == pr[preL] )break;
}
int numLeft = index - inL;
create(t->l, preL+, preL+numLeft, inL, index-);
create(t->r, preL+numLeft+, preR, index+, inR);
} void post_display(const node *t)
{
if(t==NULL)
return ;
post_display(t->l);
post_display(t->r);
printf("%c ",t->data);
} int main()
{ memset(pr,'\0',sizeof(pr));
memset(in,'\0',sizeof(in)); while(cin>>pr&&cin>>in)
{
node *tree=NULL;
if(strlen(pr)==strlen(in))
{
create(tree,,strlen(pr)-,,strlen(pr)-);
cout<<"build tree ok"<<endl;
}
//cout<<tree<<endl<<tree->l<<endl<<tree->r<<endl;
post_display(tree);
cout<<endl;
memset(pr,'\0',sizeof(pr));
memset(in,'\0',sizeof(in));
} return ;
} /*
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 35;
char in[maxn];
char pre[maxn];
struct node {
char data;
node *lchild;
node *rchild;
}; node *Create(int preL, int preR, int inL,int inR) {
if ( preL > preR ) return NULL;
node *root = new node();
root->data = pre[preL];
int index;
for ( index = inL; index <= inR; index++ ) {
if ( in[index] == pre[preL] )break;
}
int numLeft = index - inL;
root->lchild = Create(preL+1, preL+numLeft, inL, index-1);
root->rchild = Create(preL+numLeft+1, preR, index+1, inR);
return root;
} void PostOrderTraversal(node *root) {
if ( root != NULL ) {
PostOrderTraversal(root->lchild);
PostOrderTraversal(root->rchild);
cout << root->data << " ";
}
}
int main() {
int n;
cin >> n; for ( int i = 0; i < n; i++ )
cin >> pre[i];
for ( int i = 0; i < n; i++ )
cin >> in[i];
node *root=NULL;
root = Create(0,n-1,0,n-1); PostOrderTraversal(root); return 0;
}
*/
tz@HZAU
2019/3/16
【C++】根据二叉树的前序遍历和中序遍历重建二叉树并输出后续遍历的更多相关文章
- 数据结构实习 problem L 由二叉树的中序层序重建二叉树
由二叉树的中序层序重建二叉树 writer:pprp 用层序中序来重建二叉树 代码点这里 其实本质上与前序中序建立二叉树没有什么太大区别 大概思路: 递归解法,对当前层进行处理,通过层序遍历可以得到当 ...
- lintcode :前序遍历和中序遍历树构造二叉树
解题 前序遍历和中序遍历树构造二叉树 根据前序遍历和中序遍历树构造二叉树. 样例 给出中序遍历:[1,2,3]和前序遍历:[2,1,3]. 返回如下的树: 2 / \ 1 3 注意 你可以假设树中不存 ...
- java编写二叉树以及前序遍历、中序遍历和后序遍历 .
/** * 实现二叉树的创建.前序遍历.中序遍历和后序遍历 **/ package DataStructure; /** * Copyright 2014 by Ruiqin Sun * All ri ...
- LintCode-73.前序遍历和中序遍历树构造二叉树
前序遍历和中序遍历树构造二叉树 根据前序遍历和中序遍历树构造二叉树. 注意事项 你可以假设树中不存在相同数值的节点 样例 给出中序遍历:[1,2,3]和前序遍历:[2,1,3]. 返回如下的树: ...
- 剑指offer面试题:输入某二叉树的前序遍历和中序遍历,输出后序遍历
二叉树的先序,中序,后序如何遍历,不在此多说了.直接看题目描述吧(题目摘自九度oj剑指offer面试题6): 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结 ...
- 027依据前序遍历和中序遍历,重建二叉树(keep it up)
剑指offer中题目:http://ac.jobdu.com/problem.php?pid=1385 题目描写叙述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.如果输入的前序遍历和中 ...
- 【算法编程 C++ Python】根据前序遍历、中序遍历重建二叉树
题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7, ...
- 剑指offer--(根据前序遍历和中序遍历)重建二叉树
题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7, ...
- [leetcode/lintcode 题解] 前序遍历和中序遍历树构造二叉树
[题目描述] 根据前序遍历和中序遍历树构造二叉树. 在线评测地址: https://www.jiuzhang.com/solution/construct-binary-tree-from-preor ...
随机推荐
- .Net IOC框架入门之三 Autofac
一.简介 Autofac是.NET领域最为流行的IOC框架之一,传说是速度最快的一个 目的 1.依赖注入的目的是为了解耦. 2.不依赖于具体类,而依赖抽象类或者接口,这叫依赖倒置. 3.控制反转即 ...
- 第二周 数据分析之展示 Matplotlib基础绘图函数实例
Pyplot基础图表函数 Pyplot饼图的绘制: Pyplot直方图的绘制: Pyplot极坐标图的绘制: Pyplot散点图的绘制: 单元小结: import numpy as np import ...
- gitlab+PHP 自动部署设计方案
2018-9-26 14:00:39 星期三 场景: 由于某种情况, 不能使用Jenkins, so......只有自己实现了 看图: webUI 设计方案, - 文件夹A, 用来存放git分支- 文 ...
- redis-hash
Hash操作,redis中Hash在内存中的存储格式如下图: hset(name, key, value) # name对应的hash中设置一个键值对(不存在,则创建:否则,修改) # 参数: # n ...
- Eclipse安装git插件以及关联导入GitHub项目
一.Eclipse配置git 1.查看自己eclipse的版本 打开eclipse 导航: help->AboutEclipse 如图: 2.检查Eclipse中是否已安装Git插件 菜单栏He ...
- chattr和lsattr的基本用法
lsattr filename 查看一个文件的属性 chattr filename 改变一个文件的属性 主要用途:实现文件的原有内容不允许改变,但可以增加新行,则需通过改变文件的属性来实现. ch ...
- C# 集合已修改 可能无法执行枚举操作 zz
今天编写程序时 修改了list集合 在foreach时报 “集合已修改:可能无法执行枚举操作.”错误. 首先想到的是没有锁定集合对象. 增加了 private readonly object sync ...
- get、put、post、delete含义与区别
1.GET请求会向数据库发索取数据的请求,从而来获取信息,该请求就像数据库的select操作一样,只是用来查询一下数据,不会修改.增加数据,不会影响资源的内容,即该请求不会产生副作用.无论进行多少次操 ...
- 2017-2018 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2017)
A. Airport Coffee 设$f_i$表示考虑前$i$个咖啡厅,且在$i$处买咖啡的最小时间,通过单调队列优化转移. 时间复杂度$O(n)$. #include<cstdio> ...
- ArrayList, LinkedList, Vector - dudu:史上最详解
ArrayList, LinkedList, Vector - dudu:史上最详解 我们来比较一下ArrayList, LinkedLIst和Vector它们之间的区别.BZ的JDK版本是1.7.0 ...