【7005】二叉树的遍历问题2

来源:互联网 发布:开源三网合一源码下载 编辑:程序博客网 时间:2024/06/06 09:59

Time Limit: 10 second
Memory Limit: 2 MB

问题描述
输入一棵二叉树的中序和后序遍历序列,输出其前序遍历序列。

Input

输入文件共两行,第一行一个字符串,表示树的中序遍历,第二行一个字符串,表示树的后序遍历。树的结点一律用小写字母表示。

Output

输出文件仅一行,表示树的后前序遍历的序列。 

Sample Input

dbeacdebca

Sample Output

abdec

【题解】

这个后序遍历可以把它反转一下

如debca可以反转为acbed

然后它就会变成一个特殊的前序遍历了。

原来是输出当前节点,然后访问左儿子。然后访问右儿子。

这个特殊的前序遍历则是输出当前节点。然后访问右儿子。然后访问左儿子。

即它的访问顺序改变了。

至于为什么

后序遍历是先访问左儿子。然后访问右儿子。最后输出当前节点。

根据这个规律。可以知道最后出现的节点肯定是根节点。

那倒数第二个节点是什么呢。

肯定有这样一个过程。

左子树访问完了。然后右子树也访问完了。

可以想象。访问到右子树的最低端之后。会逐级往上输出节点。

那除了根节点之外。前一个当然就是根节点的右子树的根节点了。

再前一个(倒数第三个)则为根节点的右子树的右子树的根节点

(如果根节点的右子树存在右子树,若不存在右子树只存在左子树。那它就是根节点的

右子树的左子树的根节点)

然后。根据中序遍历的规律。我们可以找到一个根节点它的左子树和右子树包括哪一些

节点。

如根节点为p

1..p-1,p+1..r则分别为它的左子树和右子树。

这是用区间表示的。如果这段区间只有一个元素。则返回这个元素。否则返回这段区间的根节点即可。

这样我们就可以求出所有节点的左儿子和右儿子了。

最后先序遍历一下就好。

用递归写!!!!!

【代码】

#include <cstdio>#include <cstring>int zhongxu[30], houxu[30],ll[30],rr[30],now;void input_data(){char s[30]; //输入字符串之后。把字母转换成数字。a..z对应1..26scanf("%s", s); //houxu和zhongxu两个数组对应后序遍历和中序遍历的结果。int length = strlen(s);//strlen为获取某个字符串的长度的函数。它包含在cstring头文件中for (int i = 1; i <= length; i++)zhongxu[i] = s[i - 1] - 'a' + 1;zhongxu[0] = length;scanf("%s", s);for (int i = 1; i <= length; i++)houxu[i] = s[i - 1] - 'a' + 1;}int sear_ch(int l,int r) //返回l..r这个区间内的根节点。{if (l > r)return 0;if (l == r) //如果只有一个元素。则直接返回这个元素。return houxu[now--];int key2 = houxu[now];//获取这段区间的根节点。houxu遍历是用来获取根节点的!int pp;for (int i = l; i <= r; i++)//而中序遍历则可以确定这个根节点的左子树和右子树所在的区间。if (zhongxu[i] == key2){pp = i;break;}now--;//这时指针指向下一个子树的根节点 优先是右子树(如果有右子树)rr[key2] = sear_ch(pp+1, r);//寻找l..r这个区间的根节点的左儿子和右儿子。ll[key2] = sear_ch(l, pp-1);return key2;//返回这个区间的根节点给这个根节点的爸爸。}void xianxu(int t)//这是找到所有节点的左儿子和右儿子之后进行先序遍历。{char key = t + 'a' - 1;//把数字转成字母。putchar(key);if (ll[t] != 0)xianxu(ll[t]);if (rr[t] != 0)xianxu(rr[t]);}void get_ans(){int root = houxu[zhongxu[0]];//找到整棵树的根节点。now = zhongxu[0];//获取遍历序列的长度。int p;for (int i = 1;i <= zhongxu[0];i++)//获取这个根节点的位置if (zhongxu[i] == root)//以期找到这个根节点的左子树和右子树所在的区间。{p = i;break;}now--;//houxu[now]指向下一个子树的根节点(优先右子树。如果不存在右子树则指向左子树的根节点)rr[root] = sear_ch(p + 1, zhongxu[0]);ll[root] = sear_ch(1, p - 1);xianxu(root);//所有节点的左儿子和右儿子都确定了。直接输出这棵树的先序遍历结果。}int main(){input_data();get_ans();return 0;}



0 0