import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
public class Main
{
//二叉树节点定义
static class TreeNode
{
int data;
TreeNode leftChild;
TreeNode rightChild;
public TreeNode(int data)
{
this.data = data;
}
}
public static void aftOrder(TreeNode root)
{
if(root.leftChild != null)
{
aftOrder(root.leftChild);
}
if(root.rightChild != null)
{
aftOrder(root.rightChild);
}
System.out.print(root.data + " ");
}
public static int NodeNum = 0;
public static TreeNode getTree(int[] preOrders, int[] midOrders,
int PStart, int PEnd,
int MStart, int MEnd)
{
NodeNum++;
//构造当前的根节点
TreeNode root = new TreeNode(preOrders[PStart]);
//如果子树在先序或者中序中的起始位置与结束位置相同
//表明只有一个元素了,直接返回该元素作为一个叶子节点
if(PStart == PEnd || MStart == MEnd)
{
return root;
}
//在中序中寻找左右子树分割点位置
int MidLoc = -1;
for(int i=MStart; i<=MEnd; i++)
{
if(preOrders[PStart] == midOrders[i])
{
MidLoc = i;
break;
}
}
//如果没找到分割点表明不能构造二叉树
if(MidLoc == -1)
{
return null;
}
//在中序中计算左右子树节点的数目
int LeftCount = MidLoc - MStart;
int RightCount = MEnd - MidLoc;
//递归构造左子树
if(LeftCount > 0)
{
//左子树在先序中的起始位置
int LeftPStart = PStart + 1;
//左子树在先序中的结束位置
int LeftPEnd = LeftPStart + LeftCount - 1;
//左子树在中序中的起始位置
int LeftMStart = MidLoc - LeftCount;
//左子树在中序中的结束位置
int LeftMEnd = MidLoc - 1;
//进入递归构造左子树
root.leftChild = getTree(preOrders, midOrders,
LeftPStart, LeftPEnd,
LeftMStart, LeftMEnd);
}
//递归构造右子树
if(RightCount > 0)
{
//右子树在先序中的起始位置
int RightPStart = PStart + LeftCount + 1;
//右子树在先序中的结束位置
int RightPEnd = RightPStart + RightCount - 1;
//右子树在中序中的起始位置
int RightMStart = MidLoc + 1;
//右子树在中序中的结束位置
int RightMEnd = MidLoc + RightCount;
//进入递归构造右子树
root.rightChild = getTree(preOrders, midOrders,
RightPStart, RightPEnd,
RightMStart, RightMEnd);
}
//返回构造出来的树根
return root;
}
public static void main(String[] args) throws IOException
{
int[] preOrders = null;
int[] midOrders = null;
StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
while (st.nextToken() != StreamTokenizer.TT_EOF)
{
NodeNum = 0;
int m = (int) st.nval;
preOrders = new int[m];
midOrders = new int[m];
for (int i = 0; i < m; i++)
{
st.nextToken();
preOrders[i] = (int) st.nval;
}
for (int i = 0; i < m; i++)
{
st.nextToken();
midOrders[i] = (int) st.nval;
}
TreeNode root = getTree(preOrders, midOrders, 0, preOrders.length - 1, 0, midOrders.length - 1);
if(NodeNum == preOrders.length && root != null)
{
aftOrder(root);
System.out.println();
}
else
{
System.out.println("No");
}
}
}
}
分享到:
相关推荐
python 四种方法解析重建二叉树,七种方法遍历二叉树 四种方法解析重建二叉树包括: 1、通过对象实例的左右儿子方法重建 2、通过键盘输入先序遍历重建 3、通过先序遍历的列表重建 4、通过层序遍历列表重建 七种方法...
前序和中序重建二叉树并包含父节点
### C语言实现二叉树的重建源码解析 在计算机科学中,二叉树是一种重要的数据结构,广泛应用于算法设计和程序开发中。本篇文章将深入解析如何使用C语言实现二叉树的重建,以及其背后的逻辑与算法原理。 #### ...
【重建二叉树】是计算机科学中一个经典的数据结构问题,主要出现在算法和数据结构的面试中,尤其在像《剑指Offer》这样的面试指南中经常出现。这道题目要求根据给定的前序遍历和中序遍历序列来重建原始的二叉树结构...
重建二叉树.md
"重建二叉树1" 本资源摘要信息主要...重建二叉树是数据结构和算法中一个非常重要的问题,它可以用来描述二叉树的结构和遍历方式。通过使用递归和深度优先遍历,我们可以重建二叉树,并且可以应用于各种实际问题中。
在本课程设计中,重点是通过先序和中序遍历序列来唯一地重建二叉树。 题目要求程序能够根据用户输入的先序和中序遍历序列来构建二叉树。先序遍历的顺序是根节点 -> 左子树 -> 右子树,而中序遍历的顺序是左子树 -> ...
java基础面试题重建二叉树提取方式是百度网盘分享地址
递归方法在代码的可读性上有优势,但在处理大规模数据时可能会遇到递归栈溢出的问题;而使用堆栈的方法则更适合处理大数据量的树结构重建,因为它避免了递归带来的栈空间消耗。掌握这些方法,对于深入理解树结构以及...
c++ c++_剑指offer题解之重建二叉树
python python_剑指offer第4题重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回...
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回...
基于C++的数据结构:二叉树前中后序遍历+重建+输出 以前课程作业写的代码
在二叉树的重建问题中,通常涉及从两个或更多的序列(如先序遍历和中序遍历)恢复二叉树的结构。这里的目标是根据先序序列创建二叉树,然后进行先序和中序遍历,将遍历的节点存储到数组中,最后根据这两个数组重新...
二叉树遍历问题 二叉树遍历问题-前序, 中序, 后序二叉树遍历问题-前序, 中序, 后序二叉树遍历问题-前序, 中序, 后序二叉树遍历问题-前序, 中序, 后序二叉树遍历问题-前序, 中序, 后序二叉树遍历问题-前序...
二叉树结点染色问题,是数据结构课设的报告,代码全,文档详细
二叉树重建问题是一个经典的数据结构问题,它涉及到对二叉树的三种主要遍历方式的理解:前序遍历、中序遍历和层次遍历。在这个问题中,我们已经得到了一个二叉树的前序遍历和中序遍历序列,目标是输出该二叉树的层次...
基于二叉链表的二叉树,实现了二叉树的多种操作:添加、删除、拷贝、清空、树深度计算、父节点、兄弟节点获取、先中后序递归及非遍历、按层次遍历、中序迭代器(非递归算法)、节点查找、先序和中序序列重建二叉树、...