题目

  二叉树的前序以及后续序列,以空格间隔每个元素,重构二叉树,最后输出二叉树的三种遍历方式的序列以验证。

  输入:

  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 通过先序后序序列生成二叉树的更多相关文章

  1. [leetcode]从中序与后序/前序遍历序列构造二叉树

    从中序与后序遍历序列构造二叉树 根据一棵树的中序遍历与后序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 例如,给出 中序遍历 inorder = [9,3,15,20,7] 后序遍历 po ...

  2. 给出 中序&后序 序列 建树;给出 先序&中序 序列 建树

    已知 中序&后序  建立二叉树: SDUT 1489 Description  已知一棵二叉树的中序遍历和后序遍历,求二叉树的先序遍历 Input  输入数据有多组,第一行是一个整数t (t& ...

  3. 算法进阶面试题03——构造数组的MaxTree、最大子矩阵的大小、2017京东环形烽火台问题、介绍Morris遍历并实现前序/中序/后序

    接着第二课的内容和带点第三课的内容. (回顾)准备一个栈,从大到小排列,具体参考上一课.... 构造数组的MaxTree [题目] 定义二叉树如下: public class Node{ public ...

  4. 二叉树 遍历 先序 中序 后序 深度 广度 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  5. SDUT OJ 数据结构实验之二叉树八:(中序后序)求二叉树的深度

    数据结构实验之二叉树八:(中序后序)求二叉树的深度 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Probl ...

  6. SDUT-2804_数据结构实验之二叉树八:(中序后序)求二叉树的深度

    数据结构实验之二叉树八:(中序后序)求二叉树的深度 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 已知一颗二叉树的中序 ...

  7. 前序+中序->后序 中序+后序->前序

    前序+中序->后序 #include <bits/stdc++.h> using namespace std; struct node { char elem; node* l; n ...

  8. 【11】-java递归和非递归二叉树前序中序后序遍历

    二叉树的遍历 对于二叉树来讲最主要.最基本的运算是遍历. 遍历二叉树 是指以一定的次序访问二叉树中的每个结点.所谓 访问结点 是指对结点进行各种操作的简称.例如,查询结点数据域的内容,或输出它的值,或 ...

  9. Pre- and Post-order Traversals(先序+后序序列,建立二叉树)

    PAT甲级1119,我先在CSDN上面发布的这篇文章:https://blog.csdn.net/weixin_44385565/article/details/89737224 Suppose th ...

  10. 前序 中序 后序 遍历 递归 非递归算法 java实现

    前序遍历 非递归 public void preordernorec(TreeNode root){ //System.out.println("先序遍历(非递归):"); //用 ...

随机推荐

  1. MySQL自动化审核平台部署说明

    背景: 关于MySQL的审核的重要性就不说明了,本文的自动化审核是通过Inception和SQLAdvisor实现的,具体的使用可以看它们各自的说明文档.这里大致介绍下如何部署和使用它们,其实该文章也 ...

  2. 模块化规范Common.js,AMD,CMD

    随着网站规模的不断扩大,嵌入网页中的javascript代码越来越大,开发过程中存在大量问题,如:协同开发,代码复用,大量文件引入,命名冲突,文件依赖. 模块化编程称为迫切的需求. 所谓的模块,就是实 ...

  3. python 、mmap 实现内存数据共享

    import mmap mmap_file = None ##从内存中读取信息, def read_mmap_info(): global mmap_file mmap_file.seek(0) ## ...

  4. Linux 和 Windows 下实现多进程的方式以及管道操作

    一.多进程 1.windows 多进程 使用 #include<windows.h> 下面的 BOOL CreateProcess( LPCWSTR pszImageName, LPCWS ...

  5. net.sz.framework 框架 轻松搭建服务---让你更专注逻辑功能---初探

    前言 在之前的文章中,讲解过 threadmodel,socket tcp ,socket http,log,astart ,scripts: 都是分片讲解,从今天开始,将带大家,一窥 net.sz. ...

  6. 微服务架构的简单实现-Stardust

    微服务架构,一个当下比较火的概念了.以前也只是了解过这方面的概念,没有尝试过.想找找.NET生态下面是否有现成的实现,可是没找到,就花了大半个月的闲暇时间,遵循着易用和简单,实现了一个微服务框架,我叫 ...

  7. 理解C++中的头文件和源文件的作用【转】

    一.C++编译模式通常,在一个C++程序中,只包含两类文件--.cpp文件和.h文件.其中,.cpp文件被称作C++源文件,里面放的都是C++的源代码:而.h文件则被称作C++头文件,里面放的也是C+ ...

  8. GET 请求复制转发一直等待响应的问题 Transfer-Encoding: chunked

    今天在做Proxy 转发请求的时候发现 GET的请求转发时一直在等待输出. 而Post等其它操作是可以的. 同事告诉我一般一直等待响应可能是输出内容长度和头部ContentLength不一致导致的, ...

  9. 关于ajax post请求跨域问题的解决心得

    最近啊,公司有个项目,需要做一个手机端APP的后台管理系统.所以用到了度文本编辑框,经过了好好一番周折,终于弄好了,带到上线的时候发现啊,只能使用ip去访问网页的时候上能穿图片他不会报跨域的问题,而使 ...

  10. Xcode上传代码到github

    1.下载GitHub的Mac客户端 2.在Finder->下载,找到双击安装 3.打开Github Desktop软件, 需要进行登录, 登录的用户名密码就是github的用户信息,(如果没有去 ...