给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列
这里有个技巧,就是层序遍历二叉树中,各节点标号的关系,左子树和其父节点的关系:index=2*index_father,比如下图中1和2,2和4,3和6;右子树和其父节点的关系:index=2*index_father+1,比如下图中1和3,2和5,3和7。所以这里就不需要先构造二叉树再遍历这么麻烦了,递归函数增加一个参数index代表层序遍历的编号,每次记录当前的根节点,并于编号绑定(用map存储,还可自动排序),参考柳神AC代码如下:
1
2 3
4 5 6 7
#include<bits/stdc++.h>
using namespace std;
int n;
vector<int> post;
vector<int> in;
map<int,int> m;//<index,node_id>
//index用于标记层序遍历每个节点的标号(从1开始),root用于记录post_order中当前根的索引
// 1
// 2 3
// 4 5 6 7
void solve(int root,int in_start,int in_end,int index){
if(in_start>in_end) return;//最后一层了
m[index]=post[root];
int i=in_start;
for(;i<in_end&&in[i]!=post[root];i++);//i是在in_order中root的位置
solve(root-(in_end-i+1),in_start,i-1,2*index);
solve(root-1,i+1,in_end,2*index+1);
}
int main(){
scanf("%d",&n);
int num;
for(int i=0;i<n;i++){
scanf("%d",&num);
post.push_back(num);
}
for(int i=0;i<n;i++){
scanf("%d",&num);
in.push_back(num);
}
solve(n-1,0,n-1,1);
for(auto it=m.begin();it!=m.end();it++){
printf(it==m.begin()?"%d":" %d",it->second);
}
}
已知后序和中序,还能这样:
原文链接:https://blog.csdn.net/liuchuo/article/details/81436657
private static Node build(int[] postOrder, int[] inOrder, int postStart, int postEnd, int inStart, int inEnd) {
if (postStart > postEnd) {
return null;
}
if (postStart == postEnd) {
return new Node(postOrder[postStart]);
}
int root = postOrder[postEnd--];
//find root in inOrder
int inIndex = -1;
for (int i = inStart; i <= inEnd; i++) {
if (root == inOrder[i]) {
inIndex = i;
break;
}
}
//recursion build
int leftSize = inIndex - inStart;
int rightSize = inEnd - inIndex;
Node rootNode = new Node(root);
rootNode.left = build(postOrder, inOrder,
postStart, postStart + leftSize - 1,
inStart, inIndex - 1);
rootNode.right = build(postOrder, inOrder, postEnd - rightSize + 1, postEnd, inIndex + 1, inEnd);
return rootNode;
}