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

来源:互联网 发布:吾爱营销软件 编辑:程序博客网 时间:2024/06/10 07:59

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{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 层所有的结点都连续集中在最左边,这就是完全二叉树。
不允许最后一层的某个节点前缺少节点。

 
原创粉丝点击