剑指offer每日一刷-2017年11月13日

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

注明:

二叉树:
 
前序遍历:根节点 ->左子树 ->右子树
  中序遍历:左子树 ->根节点 ->右子树
  后序遍历:左子树 ->右子树 ->根节点


方法一:递归调用重建二叉树的方法,
以及调用JDK中的API方法Arrays.copyOfRange(int[],fromIndex,toIndex); 
复制出数组中索引在区间[fromIndex,toIndex)中的元素

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

{4,7,2,1,5,3,8,6},
 *则重建二叉树并返回.
 *
 *二叉树:
 *前序遍历:根节点 ->左子树 ->右子树
 *中序遍历:左子树 ->根节点 ->右子树
 *后序遍历:左子树 ->右子树 ->根节点
 *例如:  
 *	树:a
 *	  / \
 *	  b	 c
 *	 / \
 *  d   f
 *   \  /
 *   e  g
 *  
 *  前序遍历:a b d e f g c
 *  中序遍历:d e b g f a c
 *  
 *  可以发现一个规律 前序遍历的第一个节点是根节点,
 *  在中序遍历中根节点的两侧分别是根节点的左子树和右子树
 *  可以通过该规律遍历递归重建二叉树
 *  
 *  树的定义为:
 *
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
 

public class BinaryTree {
	
	//重建二叉树的方法
	//pre前序遍历的数组   in中序遍历的数组
	public TreeNode reConstructBinaryTree(int[] pre, int[] in){
		if(pre.length==0 || in.length==0 || pre.length!=in.length){
			return null;
		}
		
		//创建二叉树,并设置根节点		
		TreeNode tree = new TreeNode(pre[0]); 
		
		//遍历前序数组
		for(int i=0;i<pre.length;i++){
			if(pre[0] == in[i]){
				//JDK的API函数Arrays.copyOfRange(int[],fromIndex,toIndex); 复制出数组中索引在区间[fromIndex,toIndex)中的元素
				//递归调用reConstructBinaryTree()方法,根据根节点分别重建左子树和右子树
				tree.left=reConstructBinaryTree(Arrays.copyOfRange(pre, 1, i+1),Arrays.copyOfRange(in, 0, i));
				tree.right=reConstructBinaryTree(Arrays.copyOfRange(pre, i+1, pre.length),Arrays.copyOfRange(in,i+1, in.length));
			}
		}
		
		return tree;
	}
}

方法二:

/**
 * 中心思想还是根据前面写的BinarySearch类中的实现方法进行,
 * 唯一的区别就是不调用jdk的工具类中的Arrays.copyOfRange()了
 * 自己定义一个类似的方法,来实现这个功能
 * 
 */

public class BinaryTree2 {
	public TreeNode reConstructBinaryTree(int[] pre,int[] in){
		if(pre.length==0||in.length==0||pre.length != in.length){
			return null;
		}
		
		TreeNode tree = new TreeNode(pre[0]);
		
		for(int i=0;i<pre.length;i++){
			if(pre[0] == in[i]){
				tree.left=reConstructBinaryTree(getChild(pre,1,i+1),getChild(in,0,i));
				tree.right=reConstructBinaryTree(getChild(pre,i+1,pre.length),getChild(in,i+1,in.length));
			}
		}
		
		return tree;
		
	}
	
	private int[] getChild(int[] array,int i,int j){
		int length =j-i;
		int[] newArray = new int[length];
		for(int k=i,m=0;k<j;k++,m++){
			newArray[m] = array[k];
		}
		return newArray;
		
	}
	

}





回顾知识点:



二叉树有以下几个性质:TODO(上标和下标)
性质1:二叉树第i层上的结点数目最多为 2{i-1} (i≥1)。(2{k-1}是2的k-1次幂)
性质2:深度为k的二叉树至多有2{k}-1个结点(k≥1)。(2{k}是2的k次幂)
性质3:包含n个结点的二叉树的高度至少为log2 (n+1)。
性质4:在任意一棵二叉树中,若终端结点的个数为n0,度为2的结点数为n2,则n0=n2+1。


满二叉树(Full Binary Tree):
国内定义:
除最后一层无任何子节点外,每一层上的所有结点都有两个子结点二叉树。
国外定义:
a binary tree T is full if each node is either a leaf or possesses exactly two childnodes.
如果一个二叉树的节点要么是叶子节点(度为0),要么有两个子节点(度为2),那么该树就是满二叉树。
允许最后一层以外的其他层的节点没有子节点。


完全二叉树:
若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。
不允许最后一层的某个节点前缺少节点。







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值