学习目标:
掌握通过二叉树前序和中序遍历得出后序遍历的Java实现学习内容:
1.掌握前序中序后序原理 2.实现二叉树重建学习产出:
Input
第一行为一个正整数n,为二叉树节点个数。
第二行为n个正整数,为前序遍历的节点号
第三行为n个正整数,为中序遍历的节点号
Output
打印出后序遍历的序列
实现思路
前序中序遍历的原理我就不说了,上一篇博客写过了。这里就说一下如何从前序中序找到后序。
首先前序序列的第一个节点一定是根节点,因为根节点是第一个被遍历到的点,找到了根节点后,可以在中序遍历中将根节点两侧节点分开。这里举一个例子
- 前序遍历 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 1,2,3,4,5,6,7,8,9 1,2,3,4,5,6,7,8,9
- 中序遍历 3 , 2 , 5 , 4 , 6 , 1 , 8 , 7 , 9 3,2,5,4,6,1,8,7,9 3,2,5,4,6,1,8,7,9
前序遍历的第一个元素是1,然后在中序遍历中1左边的元素就是1的左子树,右边的8,7,9就是右子树。然后在前序遍历中将左子树划一堆,右子树划一堆。
这样前序遍历被分为23456和789,那么左子树的根节点是2,右子树的根节点是7。然后再中序遍历中找到2和7和他们的左右子树元素,重复上述过程,最终能够得到上述树。那么如何得到后序遍历呢?
我们每次首先是从前序遍历中得到该节点,再从中序遍历中找该节点的左右子树节点。所以我们可以逐渐递归上述过程,先遍历左子树,再遍历右子树,最后将节点输出,这不就是我们后序遍历的过程吗。
public static void Reconstruction(int l,int r)
{
if(l>=r)
return;
int root = Pre.get(pos++); //从前序遍历中获得当前节点
int index = In.indexOf(root);//从中序遍历中获得当前节点的位置
Reconstruction(l,index); //遍历该节点的左子树
Reconstruction(index+1,r); //遍历该节点的右子树
Post.add(root); //输出该节点
}
完整代码
package AizuOJ.Tree;
import java.util.ArrayList;
import java.util.Scanner;
public class ReconstructionTree {
static int n;
static int pos;
static ArrayList<Integer> Pre = new ArrayList<>();
static ArrayList<Integer> In = new ArrayList<>();
static ArrayList<Integer> Post = new ArrayList<>();
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
n = in.nextInt();
for(int i=0;i<n;i++)
{
Pre.add(in.nextInt());
}
for(int i=0;i<n;i++)
{
In.add(in.nextInt());
}
solve();
}
public static void solve()
{
pos = 0;
Reconstruction(0,n);
for(int i=0;i<n;i++)
{
if(i>0)
System.out.print(" ");
System.out.print(Post.get(i));
}
System.out.println();
}
public static void Reconstruction(int l,int r)
{
if(l>=r)
return;
int root = Pre.get(pos++);
int index = In.indexOf(root);
Reconstruction(l,index);
Reconstruction(index+1,r);
Post.add(root);
}
}
题目链接ALDS1_7_D