这个困扰我一个星期的问题终于解决了,看了网上很多博客,都只讲了大体思路,但具体关系并无未说明,所以今天我想详细解释一下。
C
/ \
/ \
B G
/ \ /
A D H
/ \
E F
这里用'la'表示中序的起点,'lb'表示(前序/后续)的起点,'n'表示序列长度,i是中序元素坐标
前序:CBADEFGH
后序:AEFDBHGC
中序:ABEDFCHG
<1> 中序+前序=后序
中序:A B E D F C H G string a
0 1 2 3 4 5 6 7
前序:C B A D E F G H string b
0 1 2 3 4 5 6 7
锁定lb寻找中序,使a[i]==b[lb]此时b[lb]=C。
在中序中C左边的ABEDF就是左子树,右边的HG就是右子树。
此时要再对左子树进行递归,la不变,lb+1,则b[lb+1]=B,B就是左子树的根节点,如此不断递归左子树直到n<=0。
左子树递归完继续对右子树递归分解,la=i+1,lb通过找规律可以发现lb=lb-la+i+1,此时lb对应的元素为中序中右子树的根节点,如此不断递归右子树直到n<=0。
代码如下:
void postorder(int n,int la,int lb)
{
if(n<=0) return ;
for(int i=la;i<=la+n-1;i++)
if(a[i]==b[lb])
{
postorder(i-la,la,lb+1);
postorder(la+n-i-1,i+1,lb-la+i+1);
cout<<b[lb];
}
}
<2> 中序+后序=前序
中序:A B E D F C H G string a
0 1 2 3 4 5 6 7
后序:A E F D B H G C string b
7 6 5 4 3 2 1 0 (注意后序编号)
锁定lb寻找中序,使a[i]==b[lb]此时b[lb]=C。
在中序中C左边的ABEDF就是左子树,右边的HG就是右子树。
此时要再对右子树进行递归,la不变,lb+1,则b[lb+1]=G,G就是右子树的根节点,如此不断递归右子树直到n<=0。
左子树递归完继续对左子树递归分解,la=i+1,lb通过找规律可以发现lb=lb+la+n-i,此时lb对应的元素为中序中左子树的根节点,如此不断递归左子树直到n<=0。
代码如下:
void preorder(int n,int la,int lb)
{
if(n<=0) return ;
for(int i=la;i<=la+n-1;i++)
if(a[i]==b[a.size()-lb-1])
{
cout<<b[a.size()-lb-1];
preorder(i-la,la,lb+la+n-i);
preorder(la+n-i-1,i+1,lb+1);
}
}