2018-10-23 09:28:38
原题链接:
1340:【例3-5】扩展二叉树
【题目描述】
由于先序、中序和后序序列中的任一个都不能唯一确定一棵二叉树,所以对二叉树做如下处理,将二叉树的空结
点用·补齐,如图所示。我们把这样处理后的二叉树称为原二叉树的扩展二叉树,扩展二叉树的先序和后序序列能
唯一确定其二叉树。
现给出扩展二叉树的先序序列,要求输出其中序和后序序列。
【输入】
扩展二叉树的先序序列。
【输出】
输出其中序和后序序列。
【输入样例】
ABD..EF..G..C..
【输出样例】
DBFEGAC DFGEBCA
【题目大意】
输入一串字符,表示树的先序序列,输出这棵树的中序序列和后序序列。
【思路】
一开始第一思路是遇到‘.’时,说明这个结点时叶节点或者它只有左孩子或者右孩子,但是发现,
只有左孩子时右孩子不要确定到底是哪个点,那怎么办呢?于是我自己手写了一下过程!大概是这
样的(以样例为例子)
箭头的指向表示这是自己的父亲,后来苦思冥想发现这样也很难实现,那就直接用数组来记录自己的孩
子和父亲吧,(好像父亲记录下来也没用)大概就是这样
就是太懒了(好丑),后面不想写。
大概的意思就是,先预处理fa[0]=-1,表示0是根节点,然后从第1个位置往后遍历,每个位置一定是
自己前面与自己靠的最近的点的孩子,如果可以是左孩子则是左孩子否则是右孩子,如果这个点已经确定
了左右孩子,就继续往前面枚举(当然遇到‘.’时不考虑),
这样先把每个点的左孩子右孩子和父亲预处理出来后,那么中序序列和后序序列就好求啦!
如果还是不知道怎么求的话,只要两个函数就好了(一个序列一个函数),直接看代码应该可以理解!
#include<bits/stdc++.h> using namespace std; char a[110]; int child[110][2],f[110]; int la; int p; void mid(int x)//中序序列 { if(a[x]=='.') return; mid(child[x][1]); cout<<a[x]; mid(child[x][2]); } void behind(int x)//后序序列 { if(a[x]=='.') return; behind(child[x][1]); behind(child[x][2]); cout<<a[x]; } int main() { scanf("%s",&a); f[0]=-1; la=strlen(a); for(int i=1;i<la;i++)//从第一个位置往后遍历 { p=0; for(int j=i-1;j>=0;j--)//找自己前面的离自己最近的还未确定自己两个孩子的点 { if(a[j]!='.') for(int k=1;k<=2;k++) if(child[j][k]==0) { child[j][k]=i; f[i]=j; p=1; break; } if(p==1) break; } } mid(0); cout<<endl; behind(0); return 0; }