【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, ...
随机推荐
- 【React踩坑记一】React项目中禁用浏览器双击选中文字的功能
常规项目,我们只需要给标签加一个onselectstart事件,return false就可以 例: <div onselectstart="return false;" & ...
- Altium Designer16设置GND和VCC线宽规则的一种操作方法及注意事项
昨天看到学弟在画电路板,看到他设置电源线线宽时出了一点问题,设置的规则最开始有作用,后来重新从原理图导入更新PCB时,电源线变绿,规则设置点更新也没有用.接下来是操作步骤: 第一步:点击Design- ...
- Spring cloud Feign不支持对象传参解决办法[完美解决]
spring cloud 使用 Feign 进行服务调用时,不支持对象参数. 通常解决方法是,要么把对象每一个参数平行展开,并使用 @RequestParam 标识出每一个参数,要么用 @Reques ...
- fatal: remote origin already exists.解决方法
git remote add origin1 http://github.com/xxx/xxx.git origin名字冲突,换一个名字 遇到这种问题时表示已经有一个origin,冲突了,可能原因是 ...
- python骚操作---Print函数用法
---恢复内容开始--- python骚操作---Print函数用法 在 Python 中,print 可以打印所有变量数据,包括自定义类型. 在 3.x 中是个内置函数,并且拥有更丰富的功能. 参数 ...
- JavaScript的垃圾回收机制与内存泄漏
常用的两种算法: 引用计数(新版浏览器已弃用,弃用原因:会出现循环引用的情况,无法进行垃圾回收,导致内存泄漏) 标记清除 引用计数法 引用计数,顾名思义一个对象是否有指向它的引用,即看栈中是否有指向要 ...
- 写个shell脚本搭载jenkins让你的程序部署飞起来
[转载请注明]: 原文出处:https://www.cnblogs.com/jstarseven/p/11399251.html 作者:jstarseven 码字挺辛苦的..... 说明 ...
- 使用Python的Django和layim实现即时通讯
看到Django和layim实现websocketde资料很少,自己就琢磨了下,顺便搭建出来了.自己要去找闲心大神授权呀. 先来看图 这是初次搭建的,今天一天就搞定.我自己接入了图灵机器人. Pyt ...
- HuffmanTree
/* 例如,对于数列{pi}={5, 3, 8, 2, 9},Huffman树的构造过程如下: 1. 找到{5, 3, 8, 2, 9}中最小的两个数,分别是2和3,从{pi}中删除它们并将和5加入, ...
- WPF中查看PDF文件 - 基于开源的MoonPdfPanel (无需安装任何PDF阅读器)问题汇总
致敬Yang-Fei—有一个简单的用法示例: http://www.cnblogs.com/yang-fei/p/4885570.html. 写MoonPdfPanel的哥们关于这个开源软件的实现介绍 ...