【Offer】[7] 【重建二叉树】
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
思路分析
- 设计的方法中输入的是两个数组,前序(pre)和中序(in)遍历数组;
- pre的第一个元素一定是根元素,然后在in中查找该跟元素,这样,整个in就分成了左右两部分,相应的就可以找到前序遍历数组中的 左右子树的两部分,然后接下来就可以用递归的方法完成;
- 测试代码涉及到了链表的遍历,此代码列出了三种遍历方式的非递归和递归的遍历算法(共6种方法)
Java代码
public class Offer007 {
public static void main(String[] args) {
int[] pre = {1,2,3,4,5,6,7};
int[] in = { 3,2,4,1,6,5,7 };
TreeNode root = reConstructBinaryTree(pre, in);
System.out.print("test1:");
preOrderNonReCurSive(root);
System.out.print("//");
inOrderNonRecursive(root);;
System.out.println();
postOrder(root);
System.out.println();
postOrderNonReCurSive(root);
}
public static TreeNode reConstructBinaryTree(int[] pre, int[] in) {
return Solution1(pre, in);
}
private static TreeNode Solution1(int[] pre, int[] in) {
if (pre == null || in == null || pre.length <= 0 || in.length <= 0 || pre.length != in.length) {
throw new IllegalArgumentException("数组不符合规范!");
}
return construct(pre, in, 0, pre.length-1, 0, in.length-1);
}
/**
* 构造二叉树的函数
* @param pre 前序遍历数组
* @param in 中序遍历数组
* @param pStart 前序遍历数组的起始下标
* @param pEnd 前序遍历数组的结束下标
* @param iStart 中序遍历数组的起始下标
* @param iEnd 中序遍历数组的结束下标
* @return
*/
private static TreeNode construct(int[] pre,int[] in,int pStart,int pEnd,int iStart,int iEnd) {
TreeNode root = new TreeNode(pre[pStart]);// 前序遍历数组的第一个元素为根节点
if(pStart==pEnd && iStart == iEnd) {// 数组中已有一个元素是直接返回根节点
if(pre[pStart]!=in[iStart]) {
throw new IllegalArgumentException("参数不符合规范");
}
return root;
}
int index = iStart;//记录 中序遍历数组 中 根的下标
while(index<=iEnd && root.val!=in[index]) {
index++;
}
if(index>iEnd) {
throw new IllegalArgumentException("数组不符合规范");
}
int leftLength = index - iStart; //计算左子树的长度
if(leftLength>0) {
root.left = construct(pre, in, pStart+1, pStart+leftLength, iStart, index-1);
}
if(leftLength< iEnd-iStart) { // 如果左子树的长度 < 总长度 说明有右子树
root.right = construct(pre, in, pStart+leftLength+1, pEnd, index+1, iEnd);
}
return root;
}
/**
* 前序遍历 递归
* @param tree
*/
private static void preOrder(TreeNode tree) {
if(tree == null) {
return ;
}
System.out.print(tree.val);
preOrder(tree.left);
preOrder(tree.right);
}
/**
* 前序遍历非递归
* @param tree
*/
private static void preOrderNonReCurSive(TreeNode tree) {
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode p = tree;
while(p!=null || !stack.isEmpty()) {
if(p!=null) {
System.out.print(p.val);
stack.push(p);
p=p.left;
}else {
TreeNode pop = stack.pop();
p = pop.right;
}
}
}
/**
* 中序遍历 递归
* @param tree
*/
private static void inOrder(TreeNode tree) {
if(tree == null) {
return ;
}
inOrder(tree.left);
System.out.print(tree.val);
inOrder(tree.right);
}
/**
* 中序遍历非递归
* @param tree
*/
private static void inOrderNonRecursive(TreeNode tree) {
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode p = tree;
while(p!=null || !stack.isEmpty()) {
if(p!=null) {
stack.push(p);
p=p.left;
}else {
TreeNode pop = stack.pop();
System.out.print(pop.val);
p = pop.right;
}
}
}
/**
* 后序遍历 递归
* @param tree
*/
private static void postOrder(TreeNode tree) {
if(tree == null) {
return ;
}
postOrder(tree.left);
postOrder(tree.right);
System.out.print(tree.val);
}
/**
* 后序遍历非递归
* @param tree
*/
private static void postOrderNonReCurSive(TreeNode tree) {
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode p = tree,r =null;
while(p!=null || !stack.isEmpty()) {
if(p!=null) {
stack.push(p);
p=p.left;
}else {
TreeNode peek = stack.peek();//取栈顶元素
if(peek.right!=null&&peek.right!=r) {//栈顶元素如果有右子树,且没有被访问过
p = peek.right; //转向右
stack.push(p); //将右子树压入栈中
p=p.left; //再走到最左
}else {
TreeNode pop = stack.pop(); //否则弹出栈访问
System.out.print(pop.val);
r = pop; //标记为被访问
// p = null; //重置p指针为空 ,这不可以不要
}
}
}
}
}
代码链接
【Offer】[7] 【重建二叉树】的更多相关文章
- 剑指Offer:重建二叉树【7】
剑指Offer:重建二叉树[7] 题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5 ...
- 《剑指offer》重建二叉树
本题来自<剑指offer> 重构二叉树 题目: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2 ...
- 【Java】 剑指offer(6) 重建二叉树
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的 ...
- Go语言实现:【剑指offer】重建二叉树
该题目来源于牛客网<剑指offer>专题. 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4 ...
- 剑指OFFER之重建二叉树(九度OJ1385)
题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7 ...
- 剑指offer:重建二叉树
重建二叉树的前置知识: 0.遍历二叉树: (1)前序遍历:根左右 --> 先访问根节点,再前序遍历左子树,最后前序遍历右子树: (2)中序遍历:左根右 --> 先中序遍历左子树,再访问根节 ...
- 剑指Offer 4. 重建二叉树 (二叉树)
题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7, ...
- 【剑指offer】重建二叉树
一.题目: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7 ...
- 剑指offer——04重建二叉树(Python3)
思路:在数据结构中,有一个条件反射,谈及二叉树,就递归.所以在实现重建二叉树时,也应该用到递归的思想. 在前序遍历中,根节点处于第一个:在中序遍历中,根节点的左边为左子树节点,根节点右边为右子树节点. ...
- 剑指offer——05重建二叉树
题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7, ...
随机推荐
- Unity学习--捕鱼达人笔记
1.2D模式和3D模式的区别,2D模式默认的摄像机的模式是Orthographic(正交摄像机),3D模式默认的摄像机的模式是Perspective(透视摄像机).3D会额外给你一个平衡光.3D模式修 ...
- egg 自学入门demo分享
目录 安装 项目 连接数据库 编写model 编写controller 添加路由 2018-08,本文适用于对egg有兴趣想要了解的同学 完整项目代码:https://github.com/NameH ...
- android——Fragment
谷歌官方文档的介绍: https://developer.android.com/guide/components/fragments.html#Design Fragment 表示 Activity ...
- TP5使用API时不可预知的内部异常
最常见的错误形式例如 controller不存在或者 action不存在之类的 我们第一时间想到的 就是 使用 try{}catch(){} 来捕获 例如: /** * show方法在common里定 ...
- CodeForces 526D Om Nom and Necklace
洛谷题目页面传送门 & CodeForces题目页面传送门 给定字符串\(a\),求它的每一个前缀,是否能被表示成\(m+1\)个字符串\(A\)和\(m\)个字符串\(B\)交错相连的形式, ...
- 强烈推荐优秀的Vue UI组件库
Vue 是一个轻巧.高性能.可组件化的MVVM库,API简洁明了,上手快.从Vue推出以来,得到众多Web开发者的认可.在公司的Web前端项目开发中,多个项目采用基于Vue的UI组件框架开发,并投入正 ...
- AutoCAD二次开发(.Net)之获取LSP变量的值
//https://blog.csdn.net/qq_21489689/article/details/78973787 [System.Security.SuppressUnmanagedCodeS ...
- web项目jsp中无法引入js问题
https://blog.csdn.net/C1042135353/article/details/80274685#commentBox 这篇文章超赞的,几个小时的时间看了这篇文章豁然开朗,瞬间懂了 ...
- Linux expect 介绍和用法
expect是一个自动化交互套件,主要应用于执行命令和程序时,系统以交互形式要求输入指定字符串,实现交互通信. expect自动交互流程: spawn启动指定进程---expect获取指定关键字--- ...
- java 计算器
初识java:利用swing制作一个简单的计算器,仿造window10内置计算器标准模式下的界面. 涉及学习内容: 设置窗口 设计界面按键 设置文本框:只读 String字符串操作:与double类型 ...