由于先序遍历树的规则为:根左右,因此可以得到先序遍历序列的第一个元素必为树的根结点。
再看中序遍历为:左根右,再根据根结点在中序遍历序列的位置,左侧为左子树,右侧为右子树。
其次,递归求解左子树,递归求解右子树。
如此递归到没有左右子树为止。
由先序遍历和中序遍历求解二叉树的过程,步骤如下:
①确定树的根节点。树根是当前树中所有元素在先序遍历中最先出现的元素,即先序遍历的第一个结点就是二叉树的根。
②求解树的子树。找到根在中序遍历的位置,位置左边是二叉树的左孩子,位置右边是二叉树的右孩子,
如果根结点左或右边为空,那么该方向子树为空;
如果根结点左边和右边都为空,那么根结点已经为叶子结点。
③对二叉树的左、右孩子分别进行①②,直到求出二叉树结构为止。
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();
}
}