Java面试宝典——已知先序遍历和中序遍历,如何求后序遍历

由于先序遍历树的规则为:根左右,因此可以得到先序遍历序列的第一个元素必为树的根结点。

再看中序遍历为:左根右,再根据根结点在中序遍历序列的位置,左侧为左子树,右侧为右子树。

其次,递归求解左子树,递归求解右子树。

如此递归到没有左右子树为止。

由先序遍历和中序遍历求解二叉树的过程,步骤如下:

①确定树的根节点。树根是当前树中所有元素在先序遍历中最先出现的元素,即先序遍历的第一个结点就是二叉树的根。

②求解树的子树。找到根在中序遍历的位置,位置左边是二叉树的左孩子,位置右边是二叉树的右孩子,
        如果根结点左或右边为空,那么该方向子树为空;
        如果根结点左边和右边都为空,那么根结点已经为叶子结点。

③对二叉树的左、右孩子分别进行①②,直到求出二叉树结构为止。

package demo.binarytree;
/** 
 * @author wyl
 * @time 2018年7月6日下午8:36:42
 */
public class BinaryTree {

	private Node root;
	public BinaryTree() {
		root=null;
	}
	
	/**
	 * 后序遍历
	 */
	public void postOrder(){
		this.postOrder(this.root);
	}
	public void postOrder(Node localRoot){
		if (localRoot!=null) {
			postOrder(localRoot.left);
			postOrder(localRoot.right);
			System.out.print(localRoot.data+" ");
		}
	}
	
	/**
	 * 初始化树
	 * @param preOrder
	 * @param inOrder
	 */
	public void initTree(int[] preOrder,int[] inOrder){
		this.root=this.initTree(preOrder, 0,preOrder.length-1,inOrder,0,inOrder.length-1);
	}
	
	private Node initTree(int[] preOrder, int start1, int end1, int[] inOrder, int start2, int end2) {
		if (start1>end1||start2>end2) {
			return null;
		}
		/**
		 * 先序的第一个元素即为根结点
		 * 获取根结点元素,并构建结点
		 */
		int rootData=preOrder[start1];
		Node head=new Node(rootData);
		/**
		 * 找到根结点所在的位置
		 */
		int rootIndex=findIndexArray(inOrder,rootData,start2,end2);
		int offSet=rootIndex-start2-1;
		/**
		 * 构建左子树
		 */
		Node left=initTree(preOrder, start1+1, start1+1+offSet, inOrder, start2, start2+offSet);
		/**
		 * 构建右子树
		 */
		Node right=initTree(preOrder, start1+offSet+2, end1, inOrder, rootIndex+1, end2);
		head.left=left;
		head.right=right;
		return head;
	}

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

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		BinaryTree binaryTree=new BinaryTree();
		int[] preOrder={1,2,4,8,9,5,10,3,6,7};
		int[] inOrder={8,4,9,2,10,5,1,6,3,7};
		binaryTree.initTree(preOrder, inOrder);
		System.out.println("~~~~~~~~~~~~~后序遍历~~~~~~~~~~~~~");
		binaryTree.postOrder();
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Baymax_wyl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值