【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, ...
随机推荐
- java-极光推送教程
一.准备工作: 1.访问极光推送官网:https://www.jiguang.cn/accounts/login/form 2.注册登陆,拿到appKey和masterSecret 3.创建一个应用, ...
- FLV协议5分钟入门浅析
FLV协议简介 FLV(Flash Video)是一种流媒体格式,因其体积小.协议相对简单,很快便流行开来,并得到广泛的支持. 常见的HTTP-FLV直播协议,就是使用HTTP流式传输通过FLV封装的 ...
- c#小灶——常量、变量和赋值
常量 常量很好理解,和变量相对,就是不会变的量.比如,1就是常量,3.6也是常量,‘a’也是常量,“aaaaa”也是常量,只是不同类型.这些都是表面上一眼就看出来的常量,还有一种表面上看不出来的常量, ...
- java集合类的相关转换
下面的的案例,基本上是以代码为主,文字的描述较少,后期有时间会继续添加. ArrayToList public void ArrayToList() { System.out.println(&quo ...
- 重读《学习JavaScript数据结构与算法-第三版》-第2章 ECMAScript与TypeScript概述
定场诗 八月中秋白露,路上行人凄凉: 小桥流水桂花香,日夜千思万想. 心中不得宁静,清早览罢文章, 十年寒苦在书房,方显才高志广. 前言 洛伊安妮·格罗纳女士所著的<学习JavaScript数据 ...
- (二十一)c#Winform自定义控件-气泡提示
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- (二十六)c#Winform自定义控件-有确定取消的窗体(二)
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- Vue-Router中History模式
目录 history路由 官方示例 Express中间件 客户端兜底404 示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在 ...
- Java后台解决跨域问题
首先说一下什么是跨域? JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象.那什么是跨域呢,简单地理解就是因为JavaScript同源策略的限制,a.com域名下的js无法操作b.c ...
- 如何使用python records 库优雅的操作数据库
今天要介绍的这个python第三方库非常厉害,完美操作各种数据库.名字叫 records, 在网上很少有这个库的相关资料,但是在开源社区可是很火热的哦.如果这还不能打消你的顾虑,再告诉你一件事:如果你 ...