题目描述

  输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
  

思路分析

  1. 设计的方法中输入的是两个数组,前序(pre)和中序(in)遍历数组;
  2. pre的第一个元素一定是根元素,然后在in中查找该跟元素,这样,整个in就分成了左右两部分,相应的就可以找到前序遍历数组中的 左右子树的两部分,然后接下来就可以用递归的方法完成;
  3. 测试代码涉及到了链表的遍历,此代码列出了三种遍历方式的非递归递归的遍历算法(共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代码-Java

【Offer】[7] 【重建二叉树】的更多相关文章

  1. 剑指Offer:重建二叉树【7】

    剑指Offer:重建二叉树[7] 题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5 ...

  2. 《剑指offer》重建二叉树

    本题来自<剑指offer> 重构二叉树 题目: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2 ...

  3. 【Java】 剑指offer(6) 重建二叉树

    本文参考自<剑指offer>一书,代码采用Java语言.  更多:<剑指Offer>Java实现合集 题目 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的 ...

  4. Go语言实现:【剑指offer】重建二叉树

    该题目来源于牛客网<剑指offer>专题. 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4 ...

  5. 剑指OFFER之重建二叉树(九度OJ1385)

    题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7 ...

  6. 剑指offer:重建二叉树

    重建二叉树的前置知识: 0.遍历二叉树: (1)前序遍历:根左右 --> 先访问根节点,再前序遍历左子树,最后前序遍历右子树: (2)中序遍历:左根右 --> 先中序遍历左子树,再访问根节 ...

  7. 剑指Offer 4. 重建二叉树 (二叉树)

    题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7, ...

  8. 【剑指offer】重建二叉树

    一.题目: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7 ...

  9. 剑指offer——04重建二叉树(Python3)

    思路:在数据结构中,有一个条件反射,谈及二叉树,就递归.所以在实现重建二叉树时,也应该用到递归的思想. 在前序遍历中,根节点处于第一个:在中序遍历中,根节点的左边为左子树节点,根节点右边为右子树节点. ...

  10. 剑指offer——05重建二叉树

    题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7, ...

随机推荐

  1. 并发知识(2)——关于Thread

    一些容易混淆的知识点 sleep vs wait sleep是Thread,wait是Object方法 wait和notify只能在同步代码块中调用 wait释放锁资源,sleep不释放锁资源 唤醒条 ...

  2. Mybatis学习笔记之---环境搭建与入门

    Mybatis环境搭建与入门 (一)环境搭建 (1)第一步:创建maven工程并导入jar包 <dependencies> <dependency> <groupId&g ...

  3. IDEA运行报错: Maven编译错误:不再支持源选项 5。请使用 6 或更高版本

    这里 记录下 这个问题的解决方案: 1:修改maven settings.xml 中的数据 这里的版本要对应现在使用的jdk版本 2:检查idea 配置 图中2块区域要一致 检查这块地方对应了自己的j ...

  4. Linux杀不死的进程之CPU使用率700%

    1. 问题发现 [root@zwlbs3 ~]# top i. 发现有个进程CPU使用率居然700%,COMMAND 是一些随机的字符串组成,完了~ 中标了:第一想到就是“沙雕”它,kill 命令给我 ...

  5. Java学习|多线程学习笔记

    什么是线程?     可以理解为进程中独立运行的字任务.   使用多线程:     1.继承Thread类:从源码可以看到,Thread累实现了Runnable接口.         如果多次调用st ...

  6. (十八)c#Winform自定义控件-提示框

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  7. Linux配置部署_新手向(二)——Nginx安装与配置

    目录 前言 Nginx 配置(后续补充) 小结 @ 前言 上一篇整完Linux系统的安装,紧接着就开始来安装些常用的东西吧,首先Nginx. Nginx 简介 Nginx作为转发,负载均衡,凭着其高性 ...

  8. Apache 配置 https

    本人当前的Apache版本是: ​ 由于我是yum安装的http,默认的http配置文件我就不多说了, 下面开始记录一下自己的线上配置过程: 1,进入/etc/httpd/conf.d目录,新建证书放 ...

  9. Caddy源码阅读(二)启动流程与 Event 事件通知

    Caddy源码阅读(二)启动流程与 Event 事件通知 Preface Caddy 是 Go 语言构建的轻量配置化服务器.https://github.com/caddyserver/caddy C ...

  10. c++自由的转换string和number

    string转数字 #include <string> #include <sstream> //使用stringstream需要引入这个头文件 //模板函数:将string类 ...