数据结构与算法-剑指Offer系列(6)重建二叉树-Java实现

42 篇文章 0 订阅
40 篇文章 0 订阅

题目6:重建二叉树

题目描述:

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

解题思路:

在二叉树的前序遍历序列中, 第一个数字总是树的根节点的值,在中序遍历序列中, 根节点的值在序列的中间,左子树的节点值位于根节点的值的右边,因此需要中序遍历序列,才能找到根节点的值。

根据中序遍历在根节点左右子树出现的数字,可以找到左右子树子序列。因此在实现的时候,需要根据遍历序列和节点位置来实现

需要用一个构造函数constructor(int[] preOrder,int[] InOrder,int pStart,int pEnd,int iStart,int iEnd),其中preOrder和inOrder是前序遍历序列和中序遍历序列,pStart,pEnd表示输的前序遍历开始和结尾节点位置,iStart,iEnd表示中序遍历数组的开始和结束节点位置

代码实现

package swordToOffer;

public class Num6_ReconstructBinaryTree {

	static class TreeNode {
		int val;
		TreeNode left;
		TreeNode right;
		public TreeNode(int val) {
			this.val =val;
		}
	}
	
	public static TreeNode ReconstructBinaryTree(int[] pre,int[] in) {
		if(pre==null||in==null||pre.length<=0||in.length<=0||pre.length!=in.length) {
			throw new RuntimeException("数组存在问题!");
		}
		return constructor(pre,in,0,pre.length-1,0,in.length-1);
	}
	
	public static TreeNode constructor(int[] preOrder,int[] inOrder,int pStart,int pEnd,int iStart,int iEnd) {
		TreeNode root = new TreeNode(preOrder[pStart]);
		if(pStart==pEnd&&iStart==iEnd) {
			if(preOrder[pStart]!=inOrder[iStart]) {
				throw new RuntimeException("数组存在问题!");
			}
			return root;
		}
		
		int index = iStart; //记录中序遍历序列中根节点位置
		while(root.val!=inOrder[index]&&index<=iEnd) {
			index++;		
		}
		
		if(index>iEnd)
			throw new RuntimeException("数组存在问题!");
		
		int left = index-iStart;
		//类似二分排序
		if(left>0) {
			root.left = constructor(preOrder,inOrder,pStart+1,pStart+left,iStart,index-1); //+1 是因为根节点为1 从1开始
		}
		if(left<iEnd-iStart) {
			root.right = constructor(preOrder,inOrder,pStart+left+1,pEnd,index+1,iEnd);
		}
		return root;
		
	}
	
	public static void preOrder(TreeNode node) {
		if(node==null) return ;
		System.out.print(node.val);
		preOrder(node.left);
		preOrder(node.right);
	}
	
	public static void inOrder(TreeNode node) {
		if(node==null) return;
		inOrder(node.left);
		System.out.print(node.val);
		inOrder(node.right);
	}
	
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//正常二叉树
		int[] pre = { 1, 2, 4, 7, 3, 5, 6, 8 };
        int[] in = { 4, 7, 2, 1, 5, 3, 8, 6 };
        TreeNode root = ReconstructBinaryTree(pre, in);
        System.out.print("正常二叉树:");
        preOrder(root);
        System.out.print("||");
        inOrder(root);
        System.out.println();
		
        //左斜树
        int[] pre1 = { 1, 2, 3, 4, 5 };
        int[] in1 = { 5, 4, 3, 2, 1 };
        TreeNode root1 = ReconstructBinaryTree(pre1, in1);
        System.out.print("左斜树:");
        preOrder(root1);
        System.out.print("||");
        inOrder(root1);
        System.out.println();
        
        //右斜树
        int[] pre2 = { 1, 2, 3, 4, 5 };
        int[] in2 = { 5, 4, 3, 2, 1 };
        TreeNode root2 = ReconstructBinaryTree(pre2, in2);
        System.out.print("右斜树:");
        preOrder(root2);
        System.out.print("||");
        inOrder(root2);
        System.out.println();
        
        //单个节点
        int[] pre3 = { 2 };
        int[] in3 = { 2};
        TreeNode root3 = ReconstructBinaryTree(pre3, in3);
        System.out.print("单个节点树:");
        preOrder(root3);
        System.out.print("||");
        inOrder(root3);
        System.out.println();
                       
	}		

}

分析

  • 对二叉树的前序、中序遍历的理解。通过不同的遍历划分出左右子树对应的子序列
  • 分析复杂问题时,将二叉树的大问题分解为左右紫薯的问题,可以采用递归解决

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值