二叉树的重构
先序遍历:根 -> 左 -> 右
中序遍历:左 -> 根 -> 右
后序遍历:左 -> 右 -> 根
知道任何一棵二叉树的先序和中序遍历的序列或者中序和后序的遍历序列,都能构造出唯一的一棵二叉树
下面先看一道PTA上的题引入思考
因为知道了先序遍历的特点,从第一个开始,都先从根开始。
把先序的根在中序中找到,以此分两分,左边是左子树,右边是右子树。递归分治重新生成一棵二叉树。
已知先序中序求后序
代码如下:
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
using namespace std;
char pre[50],in[50];
typedef struct node{
char data;
node *l,*r;
}btnode,*btree;
int n,sum;
btree rebuildtree(int root,int start,int end)
{
if(start>end)
return NULL;
int i;
for(i=start;i<=end;i++)
{
if(in[i]==pre[root])
break;
}
btree t=new btnode;
t->data=pre[root];
t->l=rebuildtree(root+1,start,i-1);
t->r=rebuildtree(root+i-start+1,i+1,end);
return t;
}
void h(btree root,int ans)
{
if(root==NULL)
return;
sum=max(sum,ans);
h(root->l,ans+1);
h(root->r,ans+1);
return;
}
int main()
{
int i;
btree r;
cin>>n;
for(i=1;i<=n;i++)
{
cin>>pre[i];
}
for(i=1;i<=n;i++)
{
cin>>in[i];
}
r=rebuildtree(1,1,n);
h(r,1);
cout<<sum<<endl;
return 0;
}
已知中序后序求先序(原理相同)
代码如下:
#include <iostream>
using namespace std;
typedef struct node{
char data;
node *l,*r;
}btnode,*btree;
char in[10005],post[10005];
int n;
btree rebuildtree(int root,int start,int end)
{
if(start>end)
return NULL;
int i;
for(i=start;i<=end;i++)
{
if(in[i]==post[root])
break;
}
btree t=new btnode;
t->data=post[root];
t->r=rebuildtree(root-1,i+1,end);
t->l=rebuildtree(root-end+i-1,start,i-1);
return t;
}
void print(btree root)
{
if(root==NULL)
return;
cout<<root->data<<" ";
print(root->l);
print(root->r);
return;
}
int main()
{
int i;
cin>>n;
for(i=0;i<n;i++)
{
cin>>in[i];
}
for(i=0;i<n;i++)
{
cin>>post[i];
}
btree t=rebuildtree(n-1,0,n-1);
print(t);
return 0;
}