从先序遍历和中序遍历重建二叉树

本文介绍了如何使用先序遍历和中序遍历重建二叉树的方法,包括基本思路、关键步骤以及实现代码。
package com.two;
//从先序遍历和中序遍历重建二叉树
public class BuildTreePreOrderInOrder {
	 /** 
     * Build Binary Tree from PreOrder and InOrder 
     *  _______7______ 
       /              \ 
    __10__          ___2 
   /      \        / 
   4       3      _8 
            \    / 
             1  11 
              
     */  
	/*
	 * 
	 * 1、从先序遍历中读入根节点
       2、从中序遍历中找到与根节点相等的元素,以此节点将中序序列分成两个部分,左边的为二叉树的
                          左子树,右边为二叉树的右子树;
       3、递归调用上述步骤得到根节点的左右子树
	 思路:
         先序遍历的第一个元素为根节点,在中序遍历中找到这个根节点,
         从而可以将中序遍历分为左右两个部分,
         左边部分为左子树的中序遍历,右边部分为右子树的中序遍历,
         进而也可以将先序遍历除第一个元素以外的剩余部分分为两个部分,
         第一个部分为左子树的先序遍历,第二个部分为右子树的先序遍历。
	 * 
	 * */
	public static void main(String[] args) {
		BuildTreePreOrderInOrder build = new BuildTreePreOrderInOrder();
		int[] preOrder = { 7, 10, 4, 3, 1, 2, 8, 11 };
		int[] inOrder = { 4, 10, 3, 1, 7, 11, 8, 2 };

		Node root = build.buildTreePreOrderInOrder(preOrder, 0,
				preOrder.length - 1, inOrder, 0, preOrder.length - 1);
		build.preOrder(root);
		System.out.println();
		build.inOrder(root);
	}

	public Node buildTreePreOrderInOrder(int[] preOrder, int begin1, int end1,
			int[] inOrder, int begin2, int end2) {
		if (begin1 > end1 || begin2 > end2) {
			return null;
		}
		int rootData = preOrder[begin1];
		Node head = new Node(rootData);
		int divider = findIndexInArray(inOrder, rootData, begin2, end2);
		int offSet = divider - begin2 - 1;
		Node left = buildTreePreOrderInOrder(preOrder, begin1 + 1, begin1 + 1
				+ offSet, inOrder, begin2, begin2 + offSet);
		Node right = buildTreePreOrderInOrder(preOrder, begin1 + offSet + 2,
				end1, inOrder, divider + 1, end2);
		head.left = left;
		head.right = right;
		return head;
	}

	public int findIndexInArray(int[] a, int x, int begin, int end) {
		for (int i = begin; i <= end; i++) {
			if (a[i] == x)
				return i;
		}
		return -1;
	}

	public void preOrder(Node n) {
		if (n != null) {
			System.out.print(n.val + ",");
			preOrder(n.left);
			preOrder(n.right);
		}
	}

	public void inOrder(Node n) {
		if (n != null) {
			inOrder(n.left);
			System.out.print(n.val + ",");
			inOrder(n.right);
		}
	}

	class Node {
		Node left;
		Node right;
		int val;

		public Node(int val) {
			this.val = val;
		}

		public Node getLeft() {
			return left;
		}

		public Node getRight() {
			return right;
		}

		public int getVal() {
			return val;
		}

	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值