算法思想:已知先序遍历和中序遍历,如何求后序遍历?(1)确定树的根结点。树根是当前树中所有元素在先序遍历中最先出现的元素,即先序遍历的第一个结点就是二叉树的根。(2)求解树的子树。找到根在中序遍历的位置,位置左边是二叉树的左孩子,位置右边是二叉树的右孩子,如果根结点左边或右边为空,那么该方向子树为空;如果根结点左边和右边都为空,那么根结点已经成为叶子结点。(3)对二叉树的左、右孩子分别进行步骤(1)(2),直到求出二叉树结构为止。
代码如下:
package com.haobi;
/*
* 已知先序遍历和中序遍历,如何求后序遍历?
*
* (1)确定树的根结点。树根是当前树中所有元素在先序遍历中最先出现的元素,即先序遍历的第一个结点就是二叉树的根。
* (2)求解树的子树。找到根在中序遍历的位置,位置左边是二叉树的左孩子,位置右边是二叉树的右孩子,
* 如果根结点左边或右边为空,那么该方向子树为空;如果根结点左边和右边都为空,那么根结点已经成为叶子结点。
* (3)对二叉树的左、右孩子分别进行步骤(1)(2),直到求出二叉树结构为止。
*/
//定义结点结构
class Node3{
public int data;
public Node3 left;
public Node3 right;
public Node3(int data) {
this.data = data;
this.left = null;
this.right = null;
}
public Node3() {}
}
public class Test3 {
//定义根结点
private Node3 root;
//构造方法
public Test3() {
root = null;
}
/**
* 后序遍历方法递归实现
* @param root
*/
public void postOrder(Node3 root) {
if(root != null) {
postOrder(root.left);
postOrder(root.right);
System.out.print(root.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);
}
/**
* 递归构建左右子树
* @param preOrder
* @param start1
* @param end1
* @param inOrder
* @param start2
* @param end2
* @return
*/
public Node3 initTree(int[] preOrder, int start1, int end1, int[] inOrder, int start2, int end2) {
if(start1 > end1 || start2 > end2) {
return null;
}
int rootData = preOrder[start1];
Node3 head = new Node3(rootData);
//从中序遍历里找到根结点所在的位置
int rootIndex = findIndexInArray(inOrder, rootData, start2, end2);
//offSet代表左子树的长度-1(也就是中序遍历中,左子树最后一个元素的下标)
int offSet = rootIndex - start2 - 1;
//递归构建左子树
Node3 left = initTree(preOrder, start1+1, start1+1+offSet, inOrder, start2, start2+offSet);
//递归构建右子树
Node3 right = initTree(preOrder, start1+offSet+2, end1, inOrder, rootIndex+1, end2);
head.left = left;
head.right = right;
return head;
}
/**
* 找到x在数组中的下标
* @param a
* @param x
* @param begin
* @param end
* @return
*/
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 static void main(String[] args) {
Test3 tree = new Test3();
int[] preOrder = {1,2,4,8,9,5,10,3,6,7};
int[] inOrder = {8,4,9,2,10,5,1,6,3,7};
tree.initTree(preOrder, inOrder);
System.out.print("二叉树的后序遍历:");
tree.postOrder(tree.root);
}
}
程序输出结果如下:
二叉树的后序遍历:8 9 4 10 5 2 6 7 3 1