【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, ...
随机推荐
- 同时运行多个 tomcat 修改端口
修改 tomcat 配置文件,路径: tomcat_home/conf/server.xml 1.HTTP端口,默认8080,如下改为8081 <Connector connectionTim ...
- jquery EasyUi 添加节点、展开所有节点、默认选中第一个节点
感觉easyUi 的树用起来不如 Ext 的树方便,首先,root节点不太好自定义, 异步加载时,只能通过后台判断生成root节点,但是这样一来有一个问题,就是第一次访问界面时, 树的初始化比较慢,大 ...
- .net core使用ocelot---第一篇 简单使用
简介原文地址 接下来你会学习,基于asp.net core 用Ocelot实现一个简单的API网关.或许你会疑问什么是API网关,我们先看下面的截图 API网关是访问你系统的入口,它包括很多东西,比如 ...
- [转载]ActiveMQ实现负载均衡+高可用部署方案
转载于 http://www.open-open.com/lib/view/open1400126457817.html 一.架构和技术介绍 1.简介 ActiveMQ 是Apache出品,最流行的, ...
- Java——类型信息
1.Class对象 Class对象是一个特殊的对象,它包含了与类有关的信息.Class对象就是用来创建类的所有常规对象的. 类是程序的一部分,每个类都有一个Class对象,每当编写并且编译一个新类,就 ...
- java线程池,阿里为什么不允许使用Executors?
带着问题 阿里Java代码规范为什么不允许使用Executors快速创建线程池? 下面的代码输出是什么? ThreadPoolExecutor executor = new ThreadPoolExe ...
- PDF.js 详情解说
pdf.js资源下载 点我下载 自定义默认加载的pdf资源 在web/view.js中我们可以通过DEFAULT_URL设置默认加载的pdf.通过上面代码我们也可以看出来可以通过后缀名来指定加载的pd ...
- Linux系统上安装OpenOffice
项目需求需要在linux上安装openOffice,本以为很简单,现在看来还是入了很多坑.理清楚就好了. 官网地址 http://download.openoffice.org/other.html ...
- Spring系列(四):Spring AOP详解
一.AOP是什么 AOP(面向切面编程),可以说是一种编程思想,其中的Spring AOP和AspectJ都是现实了这种编程思想.相对OOP(面向过程编程)来说,提供了另外一种编程方式,对于OOP过程 ...
- MYSQL--存储引擎、数据类型、约束条件、
存储引擎: 不同的数据应该有不同的处理机制 mysql存储引擎 Innodb:默认的存储引擎 查询速度相比于myisam慢 但是更安全 myisam:mysql老版本用的存储引擎 memory:内 ...