树的重建
本文收集该写了树的重建各种情景方法:
1. 已知前序遍历和中序遍历,求后序遍历
2. 已知后序遍历和中序遍历,求前序遍历
3. 已知前||中||后序遍历(保证为完全二叉树),求层序遍历
4. 已知层序遍历(保证为完全二叉树),求前、中、后序遍历
注:理解1和2时要紧扣前序、后序遍历和中序遍历的区别。
理解3和4时要紧扣完全二叉树的数组存储规律。
测试样例:
结点个数:8
前序遍历:18 34 71 91 2 55 10 15
中序遍历:91 71 34 2 18 10 55 15
后序遍历:91 71 2 34 10 15 55 18
层序遍历:18 34 55 71 2 10 15 91
1、已知前序遍历和中序遍历,求后续遍历。
#include<stdio.h>
const int N=10000;
int n,pos; //n存树的结点个数
int pre[N],in[N],post[N],idx; //pre存前序遍历,in存中序遍历,post存后序遍历
int f(int x) //返回in中等于x的下标
{
for(int i=0;i<n;i++)
if(in[i]==x)
return i;
}
void rec(int l,int r)
{
if(l>=r) return ;
int root=pre[pos++];
int m=f(root);
rec(l,m);
rec(m+1,r);
post[idx++]=root;
}
void solve()
{
pos=0;
rec(0,n);
for(int i=0;i<n;i++)
printf("%d ",post[i]);
}
int main()
{
int k;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&pre[i]);
for(int i=0;i<n;i++)
scanf("%d",&in[i]);
solve();
return 0;
}
2、已知后序遍历和中序遍历,求前序遍历
#include<stdio.h>
const int N=10000;
int n,pos; //n存树的结点个数
int pre[N],in[N],post[N],idx; //pre存后序遍历,in存中序遍历,post存前序遍历
int f(int x) //返回in中等于x的下标
{
for(int i=0;i<n;i++)
if(in[i]==x)
return i;
}
void rec(int l,int r)
{
if(l>=r) return ;
int root=pre[pos--];
int m=f(root);
rec(m+1,r);
rec(l,m);
post[idx++]=root;
}
void solve()
{
pos=n-1;
rec(0,n);
for(int i=n-1;i>=0;i--)
printf("%d ",post[i]);
}
int main()
{
int k;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&pre[i]);
for(int i=0;i<n;i++)
scanf("%d",&in[i]);
solve();
return 0;
}
3、已知前序遍历和后序遍历不可求中序遍历
4、已知前序||中序||后序遍历(保证该树为完全二叉树),求层序遍历
#include<bits/stdc++.h>
using namespace std;
int n,a[100],tree[100];
int idx=1;
void f(int x)
{
if(x > n) return ;
tree[x] = a[idx++]; //已知前序遍历,求层序遍历
f(x << 1);
//tree[x] = a[idx++]; //已知中序遍历,求层序遍历
f((x << 1) + 1);
//tree[x] = a[idx++]; //已知后序遍历,求层序遍历
}
int main(){
scanf("%d",&n);
for(int i = 1; i <= n; i++)
scanf("%d",&a[i]);
f(1);
printf("层次遍历:");
for(int i = 1; i <= n; i++)
printf("%d ",tree[i]);
return 0;
}
5、已知层序遍历,求前中后遍历
#include<stdio.h>
const int N=100;
int pre[N],in[N],post[N],tree[N],idx;;
int n;
void f(int x)
{
pre[idx++]=tree[x]; //求前序遍历
if(x<<1<=n)
f(x<<1);
//in[idx++]=tree[x]; //求中序遍历
if((x<<1)+1<=n) //记得加括号,不然会先加1后乘2
f((x<<1)+1);
//post[idx++]=tree[x]; //求后序遍历
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) //输入层遍历
scanf("%d",&tree[i]);
f(1);
for(int i=0;i<n;i++) //输出
printf("%d ",pre[i]);
return 0;
}
参考资料:
* 挑战程序设计竞赛2:算法和数据结构
* CNDN博客—— 小星星+yg https://blog.csdn.net/qq_42967669