样例:
7
2 3 1 5 7 6 4(后序-左右根)
1 2 3 4 5 6 7(中序-左根右)
后序遍历的最后一个节点一定是根节点 (先设 last = n-1) ,所以在中序遍历中等于根节点的元素左右两侧分别是左子树和右子树,last–,再递归建右子树和左子树.
层序遍历就是借助队列来输出,先进先出.
一开始理解怎么建树但是就是自己写不出来…最后还是看了别人的代码看了很久才理解的差不多…太菜了
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <map>
#include <queue>
#include <cmath>
#include <set>
#include <stack>
#include <cstring>
#include <string>
#define ll long long
using namespace std;
const int maxn = 1e4+10;
int a[50];
int b[50];
typedef struct node
{
int data;
struct node *l,*r;
}*tree;
int n;
queue<tree>q;
void creat(tree &t,int pre,int last,int len)//t,0,n-1,n
{
int inx;
int lenl,lenr;
if(len<=0)
{
t=NULL;
return;
}
else
{
t = (struct node*)malloc(sizeof(struct node));
t->data = a[last];
for(int i=0; i<n; i++)
{
if(b[i]==a[last])
{
inx = i;
break;
}
}
lenr = len-(inx-pre)-1;
creat(t->r,inx+1,last-1,lenr);
//右子树,右子树的起点,右序遍历后移的坐标,剩下节点的个数
lenl = inx-pre;
creat(t->l,pre,last-lenr-1,lenl);
}
return;
}
void ceng(tree t)
{
tree tt = t;
q.push(tt);
while(!q.empty())
{
tt = q.front();
cout<<tt->data;
if(tt->l!=NULL)
{
q.push(tt->l);
}
if(tt->r!=NULL)
{
q.push(tt->r);
}
q.pop();
if(!q.empty())
{
cout<<" ";
}
else
{
cout<<endl;
}
}
return;
}
int main()
{
cin>>n;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(int i=0; i<n; i++)
{
cin>>a[i];
}
for(int i=0; i<n; i++)
{
cin>>b[i];
}
tree t = NULL;
creat(t,0,n-1,n);
ceng(t);
return 0;
}
在递归建树时那几个参数的意思想了很久才明白😫.下面的注释我也有可能理解错了,如果错了恳请指出.
lenr = len-(inx-pre)-1;//右子树剩余的节点数
creat(t->r,inx+1,last-1,lenr);
//右子树,右子树的起点,右子树根节点在后序遍历中的坐标,右子树剩下节点的个数
lenl = inx-pre;//左子树剩余的节点数
creat(t->l,pre,last-lenr-1,lenl);
//左子树 左子树的起点, 左子树根节点在后序遍历中的坐标, 左子树剩下的节点数