剑指offer编程题Java实现——面试题6重建二叉树
题目:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出二叉树并输出他的根节点。
在二叉树的前序遍历中,第一个数字总是树的根节点。在中序遍历中,树的根节点在序列的中间,左子树的节点的值位于根节点的左边,右子树节点的值位于根节点值的右边。
因此需要扫描中序遍历序列才能找到很结点的值,由此可以找到左子树的节点的个数和右子树节点的个数,然后在前序遍历序列中找到左子树的根节点,再到中序遍历序列中找到左子树的左子树和右子树。依次递归。由于二叉树的构造本身就是用递归实现的,所以重建二叉树也用递归进行实现实很简单的。
package Solution; /**
* 剑指offer面试题6:重构二叉树
* 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历结果中都不含重复的数字。
* 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出下图的二叉树并输出他的根节点。
* 1
* / \
* 2 3
* / / \
* 4 5 6
* \ /
* 7 8
* @author GL
*
*/
public class No6ReConstructBinaryTree { public static void main(String[] args) {
int[] preOrder={1,2,4,7,3,5,6,8};
int[] inOrder={4,7,2,1,5,3,8,6};
BinaryTreeNode node=reConstruct(preOrder,inOrder);
printTree(node);
}
//二叉树节点
public static class BinaryTreeNode{
int value;
BinaryTreeNode left;
BinaryTreeNode right;
} /**
* 判断输入合法性
* @param preOrder
* @param inOrder
* @return
*/
public static BinaryTreeNode reConstruct(int[] preOrder,int[] inOrder){
if(preOrder==null||inOrder==null||preOrder.length!=inOrder.length||preOrder.length<1)
return null;
return construct(preOrder,0,preOrder.length-1,inOrder,0,inOrder.length-1);
} /**
* 根据前序遍历和中序遍历构建二叉树
* @param preOrder 前序遍历序列
* @param ps 前序遍历开始位置
* @param pe 前序遍历结束位置
* @param inOrder 中序遍历序列
* @param is 中序遍历开始位置
* @param ie 中序遍历结束位置
* @return 构建的树的根节点
*/
public static BinaryTreeNode construct(int[] preOrder,int ps,int pe,int[] inOrder,int is,int ie){
//开始位置大于结束位置说明已经处理到叶节点了
if(ps>pe)
return null;
///前序遍历第一个数字为当前的根节点
int value=preOrder[ps];
//index为根节点在中序遍历序列中的索引
int index=is;
while(index<=ie&&inOrder[index]!=value){
index++;
}
System.out.println("当前各参数的数值为->ps:"+ps+" pe:"+pe+" is:"+is+" ie:"+ie+" index:"+index+" rootValue:"+value);
//如果在整个中序遍历中没有找到根节点说明输入的数据是不合法的
if(index>ie){
throw new RuntimeException("invalid input"+index);
}
BinaryTreeNode node=new BinaryTreeNode();
node.value=value;
//当前节点的左子树的个数为index-is
//左子树对应的前序遍历的位置在preOrder[ps+1,ps+index-is]
//左子树对应的中序遍历的位置在inOrder[is,index-1]
node.left=construct(preOrder,ps+1,ps+index-is,inOrder,is,index-1);
//当前节点的右子树的个数为ie-index
//右子树对应的前序遍历位置在preOrder[ps+index-is+1,pe]
//右子树对应的中序遍历位置在inOrder[index+1,ie]
node.right=construct(preOrder,ps+index-is+1,pe,inOrder,index+1,ie);
return node;
}
//中序遍历递归打印
public static void printTree(BinaryTreeNode node){
if(node!=null){
printTree(node.left);
System.out.print(node.value+" ");
printTree(node.right);
}
} }
剑指offer编程题Java实现——面试题6重建二叉树的更多相关文章
- 剑指offer编程题Java实现——面试题5从头到尾打印链表
题目描述* 剑指offer面试题5:从尾到头打印链表 输入一个链表的头结点,从尾到头打印出每个结点的值 解决方案一:首先遍历链表的节点后打印,典型的"后进先出",可以使用栈来实现这 ...
- 剑指offer编程题Java实现——面试题12相关题大数的加法、减法、乘法问题的实现
用字符串或者数组表示大数是一种很简单有效的表示方式.在打印1到最大的n为数的问题上采用的是使用数组表示大数的方式.在相关题实现任意两个整数的加法.减法.乘法的实现中,采用字符串对大数进行表示,不过在具 ...
- 剑指offer编程题Java实现——面试题10二进制中1的个数
题目: 请实现一个函数,输入一个整数,输出该整数二进制表示中1的个数.例如,把9表示成二进制是1001,有2位是1,该函数输出2解法:把整数减一和原来的数做与运算,会把该整数二进制表示中的最低位的1变 ...
- 剑指offer编程题Java实现——面试题7相关题用两个队列实现一个栈
剑指offer面试题7相关题目:用两个队列实现一个栈 解题思路:根据栈的先入后出和队列的先入先出的特点1.在push的时候,把元素向非空的队列内添加2.在pop的时候,把不为空的队列中的size()- ...
- 剑指offer编程题Java实现——面试题7用两个栈实现队列
题目:用两个栈实现一个队列.队列的声明如下:请实现他的两个函数appendTail和deleteHead, 分别完成在队列尾部插入节点和在队列头部删除节点的功能. package Solution; ...
- 剑指offer编程题Java实现——面试题11数值的整数次方
题目: 实现函数double power(double base,int exponent),求base的exponent次方.不得使用库函数,同时不需要考虑大数问题. 解题思路:最一般的方法实现数值 ...
- 剑指offer编程题Java实现——面试题12打印1到最大的n位数
题目:打印1到最大的n位数 输入数字n,按顺序打印输出从1到最大的n位十进制数,比如输入3,打印从1到999. 这道题考察的地方是如何表示大数问题.由于n是任意大的数组,如果n太大的话n位数就超过了l ...
- 剑指offer编程题Java实现——面试题14调整数组顺序使奇数位于偶数之前
题目: 输入一个整数数组,实现一个函数来调整该数组中数组的顺序,使得所有的奇数位于数组的前半部分,偶数位于数组的后半部分. 解题思路:数组中维护两个指针,第一个指针初始化时候指向数组头部,第二个指针初 ...
- 剑指offer编程题Java实现——面试题13在O(1)时间内删除链表节点
题目:给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间删除该节点. 由于给定的是单向链表,正常删除链表的时间复杂度是查找链表的时间复杂度即O(n),如果要求在O(1)时间复杂度内删除节点 ...
随机推荐
- ExcelUtil
package cn.com.jansh.core.util; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi ...
- CentOS下架设VNC服务器
CentOS下架设VNC服务器1.什么是VNC服务器?百度百科:VNC (Virtual Network Computer)是虚拟网络计算机的缩写.它 是一款优秀的远程控制工具软件,由著名的 AT&a ...
- bzoj 2286 [Sdoi2011]消耗战 虚树+dp
题目大意:多次给出关键点,求切断边使所有关键点与1断开的最小费用 分析:每次造出虚树,dp[i]表示将i和i子树与父亲断开费用 对于父亲x,儿子y ①y为关键点:\(dp[x]\)+=\(dismn( ...
- 阿里云上给的防止跨站和xss攻击的代码
文档说明: 1.将waf.php传到要包含的文件的目录 2.在页面中加入防护,有两种做法,根据情况二选一即可: a).在所需要防护的页面加入代码require_once('waf.php');就可以做 ...
- BNU Online Judge-29140
题目链接 http://www.bnuoj.com/bnuoj/problem_show.php?pid=29140 看到这样的题,应该想到an 与an-1 的关系,他们是会有关系的你要去找 代码 ...
- MySQL密码丢失,解决方法
我的MySQ安装路径是:D:\Program Files\MySQL 1.所以先cmd下切入盘 输入-> D: 输入->cd "D:\Program Files\MySQL\My ...
- C#中IDisposable
在Net中,由GC垃圾回收线程掌握对象资源的释放,程序员无法掌控析构函数的调用时机.对于一些非托管资源,比如数据库链接对象等,需要实现IDisposable接口进行手动的垃圾回收.那么什么时候使用Id ...
- WPF学习之数据绑定
WPF中的数据绑定提供了很强大的功能.与普通的WinForm程序相比,其绑定功能为我们提供了很多便利,例如Binding对象的自动通知/刷新,Converter,Validation Rules,Tw ...
- c#中Partial关键字的作用
1. 什么是局部类型? C# 2.0 引入了局部类型的概念.局部类型允许我们将一个类.结构或接口分成几个部分,分别实现在几个不同的.cs文件中. 局部类型适用于以下情况: (1) 类型特别大,不宜放在 ...
- Flex移动皮肤开发(三)
范例文件 mobile-skinning-part3 在关于创建Flex移动皮肤系列文章的第二部分里,我们讨论了屏幕密度(DPI)对组件皮肤以及移动应用布局所带来的影响. 我还展示了如何使用缩放应用, ...