1、给后序中序求前序,因为后序序列左右根从后往前是根右左的顺序。因此递归先造右子树,再造左子树。
2、给前序中序求后序,因为前序序列是根左右,从前往后是根左右。因此递归先造左子树再造右子树。
题目:P1030 [NOIP2001 普及组] 求先序排列
字符串版本:
题解:
#include
#include
#include
#include
#include
using namespace std;
const int N = 10010;
int pos, n;
string in_s, post_s;
int pre[N], in[N], post[N];
struct node
{
int l, r;
char w;
}T[N];
// 建树
void creat(int inl, int inr, int u)
{
// 如果是空子树 返回上一层
if(inl > inr) return ;
// 赋予当前节点值等于后序序列的右边往左数的数,左右孩子的位置
T[u].w = post_s[pos--];
T[u].l = 2 * u, T[u].r = 2 * u + 1;
//找到中序遍历序列的root节点,
int mid;
for(mid = inl; mid <= inr; mid++)
if(T[u].w == in_s[mid]) break;
// 递归创建子树. 如果是给后序序列,先遍历右边,如果是给前序序列,先遍历左边。
creat(mid + 1, inr, 2 * u + 1); //必须先递归右子树,因为后续遍历的根节点前面一些点一定是右子树的点,而我们是根据后续遍历的根节逐渐前移来去找递归的
creat(inl, mid - 1, 2 * u);
}
// 进行层序遍历
void bfs()
{
int idx = 0;
queue<int> q;
q.push(1);
while(q.size())
{
node t = T[q.front()];
q.pop();
if(!idx) cout << t.w;
else cout << " " << t.w;
idx++;
if(t.l > 0 && t.l <= n) q.push(t.l);
if(t.r > 0 && t.r <= n) q.push(t.r);
}
}
void preout(int u)
{
if(T[u].w == -1) return ;
cout<<T[u].w;
preout(u * 2 );
preout(u * 2 + 1);
}
int main()
{
cin >> in_s >> post_s;
n = in_s.size();
pos = n;
in_s = " "+ in_s;
post_s = " " + post_s;
memset(T, -1, sizeof T);
// for(int i =0 ; i < n ; i ++)
// {
// cout<
// }
creat(1, n, 1);
// bfs();
// cout << endl;
// cout<<"----"<
preout(1);
return 0;
}
数字版本:
#include
#include
#include
#include
#include
using namespace std;
const int N = 10010;
int pos, n;
int pre[N], in[N], post[N];
struct node
{
int l, r, w;
}T[N];
// 建树
void creat(int inl, int inr, int u)
{
if(inl > inr) return ;
T[u].w = post[pos--];
T[u].l = 2 * u, T[u].r = 2 * u + 1;
int mid;
for(mid = inl; mid <= inr; mid++)
if(T[u].w == in[mid]) break;
creat(mid + 1, inr, 2 * u + 1); //必须先递归右子树,因为后续遍历的根节点前面一些点一定是右子树的点,而我们是根据后续遍历的根节逐渐前移来去找递归的
creat(inl, mid - 1, 2 * u);
}
// 进行层序遍历
void bfs()
{
int idx = 0;
queue<int> q;
q.push(1);
while(q.size())
{
node t = T[q.front()];
q.pop();
if(!idx) cout << t.w;
else cout << " " << t.w;
idx++;
if(T[t.l].w != -1) q.push(t.l);
if(T[t.r].w != -1) q.push(t.r);
}
}
int f = 1;
void preout(int u)
{
if(T[u].w == -1) return ;
if(f == 1) cout<<T[u].w;
else
cout<<" "<<T[u].w;
f ++;
preout(u * 2 );
preout(u * 2 + 1);
}
int main()
{
cin >> n;
pos = n;
for(int i = 1; i <= n ; i ++) cin >> post[i];
for(int i = 1; i <= n ; i ++) cin >> in[i];
memset(T, -1, sizeof T);
creat(1, n, 1);
// bfs();
preout(1);
cout << endl;
return 0;
}
#include
#include
#include
#include
using namespace std;
const int N = 1e4+10;
int pre[N], in[N], post[N];
typedef struct node{
int v, l, r;
}node;
node T[N];
int n, n1 = 1;
void buildTree(int inl, int inr, int u)
{
if(inl > inr) return ;
T[u].v = pre[n1 ++];
T[u].l = u * 2;
T[u].r = u * 2 + 1;
int mid;
for(mid = inl; mid <= inr; mid ++)
if(in[mid] == T[u].v) break;
buildTree(inl, mid - 1, T[u].l);
buildTree(mid + 1, inr, T[u].r);
}
void printPost(int u)
{
if(T[u].v == -1) return ;
printPost(T[u].l);
printPost(T[u].r);
cout<<T[u].v<<" ";
}
int main()
{
cin >> n;
// n1 = n;
for(int i = 1; i <= n ; i ++) cin >> pre[i];
for(int i = 1; i <= n ; i ++) cin >> in[i];
memset(T, -1, sizeof T);
buildTree(1, n, 1);
printPost(1);
return 0;
}```