给中序前序求后序遍历
根据前序和中序求后序遍历序列
根据前序和中序的特性分析
1 首先从前序序列确定当前子树的根节点
2 然后可以根据根节点到中序序列中找到左右子树的个数
分析左右子树
3 如果左右子树数量大于零
相当于我们分别知道了左右子树在前序和中序的子序列
4 通过确立根节点的过程 我们依次确立根的左孩子左子树 以及右孩子 右子树
递归求解 回到1
根据以上步骤 可以逐步以深搜递归树的方式
把整颗树创建出来
然后再后序打印即可
#include <bits/stdc++.h>
using namespace std;
typedef struct node{char v;node* l,*r;
}*T;
/*前序遍历: GDAFEMHZ中序遍历: ADEFGHMZ后序序列: AEFDHZMG
*/
char pre[20],in[20];T ana(int s1,int e1,int s2,int e2){T p;p = (node*)malloc(sizeof(node));p->l = p->r = NULL;p->v = pre[s1];char f = pre[s1];int rt;for(rt=s2;rt<=e2;rt++)if(in[rt]==f)break;//注意这里找的是中序序列分割左右子树 int l = rt-s2,r = e2-rt;//注意找到后用rt计算左右子树的元素数量 if(l>0)p->l = ana(s1+1,s1+l,s2,rt-1);if(r>0)p->r = ana(s1+l+1,e1,rt+1,e2);return p;
}
void postOrder(T rt){if(rt){postOrder(rt->l);postOrder(rt->r);printf("%c",rt->v);}
}
int main()
{gets(pre);gets(in);T rt;rt = ana(0,strlen(pre)-1,0,strlen(in)-1);postOrder(rt);return 0;
}
给后序中序求前序序列
还是相似的步骤 这次就是后序的最后一个结点为根节点
然后还是依靠中序序列划分左右子树 然后递归分治求解
#include<bits/stdc++.h>
using namespace std;
typedef struct node{char v;node *l,*r;
}*T;
char in[20],post[20];
/*前序遍历: GDAFEMHZ中序遍历: ADEFGHMZ后序序列: AEFDHZMG
*/T ana(int p1,int p2,int i1,int i2){T p = (node*)malloc(sizeof(node));p->l=p->r = NULL;p->v = post[p2];int rt;char f = post[p2];for(rt = i1;rt<=i2;rt++)if(in[rt]==f)break;//注意这里找的是中序序列分割左右子树 int l = rt-i1,r = i2-rt; if(l>0)p->l = ana(p1,p1+l-1,i1,rt-1);if(r>0)p->r = ana(p2-r,p2-1,rt+1,i2);return p;
}
void preOrder(T rt){if(rt){printf("%c",rt->v);preOrder(rt->l);preOrder(rt->r); }
}
int main()
{gets(in);gets(post);T rt;rt = ana(0,strlen(in)-1,0,strlen(in)-1);preOrder(rt);return 0;
}
给前序后序求中序序列
我们发现 由于没有中序序列 前序我们可以知道根节点 后序也可以知道根节点
而左右子树的界限无法划分 存在不唯一解