Java 通过先序中序序列生成二叉树
题目
二叉树的前序以及后续序列,以空格间隔每个元素,重构二叉树,最后输出二叉树的三种遍历方式的序列以验证。
输入:
1 2 3 4 5 6 7 8 9 10
3 2 5 4 1 7 8 6 10 9
输出:
1,2,3,4,5,6,7,8,9,10
3,2,5,4,1,7,8,6,10,9
3,5,4,2,8,7,10,9,6,1
分析
以上述输入为例,该树的结构为:

在解决这方面问题时,需要把控这几个因素:
(1)前序的第一个元素必为根节点;
(2)中序中在根节点左边的为左子树,在根节点右边的为右子树。
抓住上面两点,就可以无限递归,从而产生一个完整的二叉树。
算法演算
前序:1 2 3 4 5 6 7 8 9 10
中序:3 2 5 4 1 7 8 6 10 9
<默认优先处理左子树>
(1)第一次:
产生节点 1。
生成左子树
先序:2 3 4 5
中序:3 2 5 4
生成右子树
前序:6 7 8 9 10
中序:7 8 6 10 9
(2)第二次
产生节点 2(由左子树得来,故为第一次结点的左子树)。
生成左子树
前序:3
中序:3
生成右子树
先序:4 5
中序:5 4
(3)第三次
产生节点 3(同上,产生左子树)
<此处限定:当先序长度小于等于1时,直接Return>
(4)第四次(因为Return,所以处理第二次产生的右子树)
产生结点 4
生成左子树
先序:null
中序:null
生成右子树
先序:5
后续:5
<此处限定:当新生成的左(右)序列为空时,则只进行右(左)序列的处理,并将为空的节点初始化为null>
……
以此类推,即可轻松生成一棵二叉树。
实现代码
package DataStructe; import java.util.ArrayList;
import java.util.Scanner; public class TreeReBuild {
/*先序(DLR)、中序(LDR)遍历对应的三个数组*/
static ArrayList<Integer> DLR=new ArrayList<Integer>();
static ArrayList<Integer> LDR=new ArrayList<Integer>();
static node root=new node(); /*二叉树的结点结构*/
static class node{
node rchild;
node lchild;
int data;
node(int ndata)
{
data=ndata;
rchild=null;
lchild=null;
}
public node() {
rchild=null;
lchild=null;
}
} /*核心算法*/
static void reBuildTreeprocess(node x,ArrayList<Integer> qx,ArrayList<Integer> zx)
{
x.data=qx.get(0);//前序第一个元素必为根节点
if(qx.size()<=1)
{
return;
}
x.lchild=new node();
x.rchild=new node();
//两个序列的拆分索引
int rootindex = 0;
int qxindex=0;
/*拆分序列*/
ArrayList<Integer>newqxleft = new ArrayList<Integer>();
ArrayList<Integer>newqxright= new ArrayList<Integer>();
ArrayList<Integer>newzxleft = new ArrayList<Integer>();
ArrayList<Integer>newzxright = new ArrayList<Integer>();
//拆分中序
for(int j=0;j<zx.size();j++)
{
if(zx.get(j)==x.data)
{
zx.remove(j);
j--;
rootindex=j;
break;
}
} //生成新的中序(左)
for(int j=0;j<=rootindex;j++){ newzxleft.add(zx.get(j));
}
//生成新的中序(右)
for(int j=rootindex+1;j<zx.size();j++)
{
newzxright.add(zx.get(j));
} //拆分前序,确定分离的元素索引
if(newzxright.isEmpty())
{
//中序右为空,前序全为左子树
for(int i=1;i<qx.size();i++)
{
newqxleft.add(qx.get(i));
}
x.rchild=null;
reBuildTreeprocess(x.lchild, newqxleft, newzxleft);
}
else{
if(newzxleft.isEmpty())
{
//中序左为空,前序全为右子树
for(int i=1;i<qx.size();i++)
{
newqxright.add(qx.get(i));
}
x.lchild=null;
reBuildTreeprocess(x.rchild, newqxright, newzxright);
}
else {
//均不为空,分别生成
outer: for(int r=0;r<qx.size();r++)
{ for(int i=0;i<newzxright.size();i++)
{ if(qx.get(r)==newzxright.get(i))
{ qxindex=r;
break outer;
}
}
} for(int t=1;t<qxindex;t++)
{
newqxleft.add(qx.get(t));
}
for(int y=qxindex;y<qx.size();y++)
{
newqxright.add(qx.get(y));
}
reBuildTreeprocess(x.lchild, newqxleft, newzxleft);
reBuildTreeprocess(x.rchild, newqxright, newzxright);
}
}
}
/*先序遍历,用于测试结果*/
static void XSearch(node x)
{
if (x==null) {
return;
}
System.out.print(x.data+",");
if (x.lchild!=null) {
XSearch(x.lchild);
} if(x.rchild!=null){
XSearch(x.rchild);
}
} /*中续遍历,用于测试结果*/
static void ZSearch(node x)
{
if (x==null) {
return;
}
if (x.lchild!=null) {
ZSearch(x.lchild);
}
System.out.print(x.data+",");
if(x.rchild!=null){
ZSearch(x.rchild);
} } /*后续遍历,用于测试结果*/
static void HSearch(node x)
{
if (x==null) {
return;
}
if (x.lchild!=null) {
HSearch(x.lchild);
}
if(x.rchild!=null){
HSearch(x.rchild);
}
System.out.print(x.data+",");
} public static void main(String[] args) {
Scanner getin=new Scanner(System.in); /*读入先序序列*/
String readydata=getin.nextLine();
String []DLRdata=readydata.split(" ");
for(int i=0;i<DLRdata.length;i++)
{
int qxdata=Integer.parseInt(DLRdata[i]);
DLR.add(qxdata);
} /*读入中序序列*/
readydata=getin.nextLine();
String[]LDRdata=readydata.split(" ");
for(int i=0;i<LDRdata.length;i++)
{
int zxdata=Integer.parseInt(LDRdata[i]);
LDR.add(zxdata);
}
reBuildTreeprocess(root, DLR, LDR); XSearch(root);
System.out.println();
ZSearch(root);
System.out.println();
HSearch(root);
System.out.println(); } }
Java 通过先序中序序列生成二叉树的更多相关文章
- 给出 中序&后序 序列 建树;给出 先序&中序 序列 建树
已知 中序&后序 建立二叉树: SDUT 1489 Description 已知一棵二叉树的中序遍历和后序遍历,求二叉树的先序遍历 Input 输入数据有多组,第一行是一个整数t (t& ...
- UVa 二叉树重建(先序+中序求后序)
题意是给出先序和中序,求出后序. 先序遍历先访问根结点,通过根结点可以在中序中把序列分为左子树部分和右子树部分,我建了一个栈,因为后序遍历最后访问根结点,所以把每次访问的根结点放入栈中.因为后序遍历先 ...
- 【IT笔试面试题整理】给定二叉树先序中序,建立二叉树的递归算法
[试题描述]: 给定二叉树先序中序,建立二叉树的递归算法 其先序序列的第一个元素为根节点,接下来即为其左子树先序遍历序列,紧跟着是右子树先序遍历序列,固根节点已可从先序序列中分离.在中序序列中找到 ...
- 二叉树 遍历 先序 中序 后序 深度 广度 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- SDUT OJ 数据结构实验之二叉树四:(先序中序)还原二叉树
数据结构实验之二叉树四:(先序中序)还原二叉树 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem ...
- PAT甲级|1151 LCA in a Binary Tree 先序中序遍历建树 lca
给定先序中序遍历的序列,可以确定一颗唯一的树 先序遍历第一个遍历到的是根,中序遍历确定左右子树 查结点a和结点b的最近公共祖先,简单lca思路: 1.如果a和b分别在当前根的左右子树,当前的根就是最近 ...
- SDUT-3343_数据结构实验之二叉树四:(先序中序)还原二叉树
数据结构实验之二叉树四:(先序中序)还原二叉树 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 给定一棵二叉树的先序遍历 ...
- PAT 甲级 1020 Tree Traversals (25分)(后序中序链表建树,求层序)***重点复习
1020 Tree Traversals (25分) Suppose that all the keys in a binary tree are distinct positive intege ...
- Java 通过先序后序序列生成二叉树
题目 二叉树的前序以及后续序列,以空格间隔每个元素,重构二叉树,最后输出二叉树的三种遍历方式的序列以验证. 输入: 1 2 3 4 5 6 7 8 9 10 3 2 5 4 1 7 8 6 10 9 ...
随机推荐
- 执行 sql 报错未缓冲查询,错误码 2014
sql语句为 SELECT COUNT(id) AS tp_count FROM `tableName` WHERE `status` = 0 AND `source` = 1 AND ( `end_ ...
- mybatis xml文件 -- 报错 invalid comparison: java.time.LocalDateTime and java.lang.String
原配置写法:<if test="assetFlaw.handleTime != null and assetFlaw.handleTime != ''"> and af ...
- php 面试常问 基础知识
字符串都是海针 数组是针海 输出及打印 echo 8%(-2); //输出结果为0 模后的正负号可无视 模前的有用 echo date('Y-m-d H:i:s',strtotime('-1 day' ...
- Microbit蓝芽配对
Microbit蓝芽配对 (Bluetooth Pairing) Microbit 可以像手机或平板与其他蓝芽装置一样,一旦做完第一次配对完就可以使用”蓝芽服务” paired with the mi ...
- Python中各种进制之间的转化
1.十进制转化为其它进制 (1)bin(x):十进制转化为二进制 [实例1] x=bin(20) # x的值为字符串'0b10100' (2)oct(x):十进制转化为八进制 [实例2] x=oc ...
- ACM1008:Elevator
Problem Description The highest building in our city has only one elevator. A request list is made u ...
- 记账APP(4)
依旧是一个表格类型的增删改查,但是呢,在用节点做,有点懵,明天加油
- 20155212 实验二 Java面向对象程序设计
20155212 实验二 Java面向对象程序设计 单元测试 三种代码 用编程去解决问题,必须学会写三种码: 伪代码 产品代码 测试代码 例: MyUtil 类解决一个百分制成绩转成"优.良 ...
- HBase核心功能模块--读书笔记
客户端Client 客户端 Client 是整个 HBase 系统的入口.使用者直接通过客户端操作 HBase.客户端 使用 HBase 的 RPC 机制与 HMaster 和 RegionServe ...
- 洛谷 P3369 【模板】普通平衡树(Treap/SBT)
题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除x数(若有多个相同的数,因只删除一个) 查询x数的排名(排名定义为比当前数小的数的个数+1.若有多 ...