前序,中序,后序序列的转换:
准备工作(全局变量):
- 1.已知前序和中序序列,求后序序列
string a,b//a用来保存前序序列,b用来保存中序序列
- 2.已知后序和中序序列,求前序序列
string a,b//a用来保存后序序列,b用来保存中序序列
接口声明:
- 1.已知前序和中序序列,求后序序列
void post(int b1,e1,int b2,int e2)//b1,e1和b2,e2分别为前序序列和中序序列的开始下标和终止下标
- 2.已知后序和中序序列,求前序序列
void pre(int b1,e1,int b2,int e2)//b1,e1和b2,e2分别为后序序列和中序序列的开始下标和终止下标
算法核心:
- 1.已知前序和中序序列,求后序序列
第一步,先利用前序序列首字符即为根节点的性质,然后找出根节点字符在中序序列中的位置,然后递归划分根节点的左子树与右子树的区间,依次输出左子树,右子树,根节点
注意:中序序列用来划分左右子树区间
架构如下
void post(int b1,e1,int b2,int e2)
{
...//边界条件是b1>e1
...//求出根节点字符在中序的位置x,意味着左子树有x-b2个字符,右子树有e2-x个字符
post(b1+1,b1+x-b2,b2,x-1);//递归到左子树
post(b1+x-b2+1,e1,x+1,e2);//递归到右子树
cout<<b[i];//最后再输出根节点
}
- 2.已知后序和中序序列,求前序序列
第一步,先利用后序序列尾字符即为根节点的性质,然后找出根节点字符在中序序列中的位置,然后递归划分根节点的左子树与右子树的区间,依次输出根节点,左子树,右子树
注意:中序序列用来划分左右子树区间
架构如下
void pre(int b1,e1,int b2,int e2)
{
...//边界条件是b1>e1
...//求出根节点字符在中序的位置x,意味着左子树有x-b2个字符,右子树有e2-x个字符
cout<<b[i];//先输出根节点
post(b1,b1+x-b2-1,b2,x-1);//递归到左子树
post(b1+x-b2,e1-1,x+1,e2);//递归到右子树
}
源代码:
#pragma warning(disable:4786)
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
string a,b;
void post(int b1,int e1,int b2,int e2);//已知前序和中序序列,求后序序列
void pre(int b1,int e1,int b2,int e2);//已知后序和中序序列,求前序序列
void post(int b1,int e1,int b2,int e2)
{
if(b1>e1)//边界条件是b1>e1
return;
for(int x=b2;x<=e2;x++)
{
if(b[x]==a[b1])
break;
}
//求出根节点字符在中序的位置x,意味着左子树有x-b2个字符,右子树有e2-x个字符
post(b1+1,b1+x-b2,b2,x-1);//递归到左子树
post(b1+x-b2+1,e1,x+1,e2);//递归到右子树
cout<<b[x];//最后再输出根节点
}
void pre(int b1,int e1,int b2,int e2)
{
if(b1>e1)//边界条件是b1>e1
return;
for(int x=b2;x<=e2;x++)
{
if(b[x]==a[e1])
break;
}
//求出根节点字符在中序的位置x,意味着左子树有x-b2个字符,右子树有e2-x个字符
cout<<b[x];//先输出根节点
pre(b1,b1+x-b2-1,b2,x-1);//递归到左子树
pre(b1+x-b2,e1-1,x+1,e2);//递归到右子树
}
int main()
{
cin>>a;
cin>>b;
//已知前序和中序序列,求后序序列
//post(0,a.size()-1,0,b.size()-1);
//cout<<endl;
//已知后序和中序序列,求前序序列
pre(0,a.size()-1,0,b.size()-1);
cout<<endl;
return 0;
}