发现自己懒得思考,不能一直刷一眼就看出结果的水题吧?
思路:
根据二叉树前中后序遍历的特性
1、前序遍历的第一个字母必是 根
2、在中序遍历的字母串中找出 根字母,那么根字母左右两边的字符串就分别是它的左、右子树
3、利用递归复原二叉树(把子树看作新的二叉树)
4、后序遍历特征:后序遍历字母串 自右至左 依次为:
最外层(总树,设为第0层)右子树的根,内1层右子树的根,内2层右子树的根….内n层右子树的根,内n层左子树的根,内n-1层左子树的根……内1层左子树的根,最外层(总树,第0层)左子树的根。把总树的左子树作为新的总树,继续递归即可。 (注意:总树的叶就是作为“单叶”这棵树本身的右根)
5、输出后序遍历时,只需按4的顺序从左到右排列,再倒置输出即可
#include<iostream> #include<cstring> using namespace std; char post[26]; int point = 0; void right_to_left(char preo[],char inor[]) { post[point++] = preo[0]; const int length = strlen(inor); if(length == 1) return ; int j = 0; for(;j<length;j++) if(inor[j] == preo[0]) break; const int flag = j; int i = ++j; char inor_temp[26],preo_temp[26]; bool tag = false;//tag标记时代、否有左or右子树 for(j=0;i<length;++i,++j) { inor_temp[j] = inor[i]; tag = true; } if(tag) { inor_temp[j] = ' '; for(i = 0,j=length-j;j<length;++i,++j) preo_temp[i] = preo[j]; preo_temp[i] = ' ';//加上字符串结束标志,不然下一次调用strlen()函数将不能成功返回长度 right_to_left(preo_temp,inor_temp); } tag = false; for(i = 0;i<flag;i++) { inor_temp[i] = inor[i]; tag = true; } if(tag) { inor_temp[i] = ' ' ; for(i=0,j=1;i<flag;++i,++j) { preo_temp[i] = preo[j]; } preo_temp[i] = ' '; right_to_left(preo_temp,inor_temp); } return ; } int main(void) { char preo[26],inor[26]; while(cin>>preo>>inor) { right_to_left(preo,inor); for(int i=--point;i>=0;i--) printf("%c",post[i]); printf(" "); } return 0; }
转自:
優YoU http://user.qzone.qq.com/289065406/blog/1299063032