解题报告-PAT- Tree Traversals Again(1086)

来源:互联网 发布:视频特效软件下载 编辑:程序博客网 时间:2024/06/03 19:01
解题报告-PAT- Tree Traversals Again
Tree Traversals Again有两种解题思路:
1、在Push和Pop的过程中记录后序序列。
2、构造先序序列和中序序列,然后build后序序列。

PAT原题链接:https://www.patest.cn/contests/pat-a-practise/1086
下面给出两种算法:
算法1:
# include <stdio.h># include <string.h># include <iostream># define MAX 60typedef struct stack{int top;int data[MAX];int flag[MAX];  //标记变量 0.表示在访问左子树,1.表示在访问右子树。只有在访问右子树弹出栈的时候才输出 }ST;/**算法思想:一个入栈出栈序列,之所以能唯一确定一颗树,就是因为,入栈顺序是中序遍历,出栈顺序是先序遍历。而先序中序可以唯一确定一颗树,那么这里我们就有两种思路:1.先保存先序遍历序列和中序遍历序列,递归调用build(n,s1,s2,ans);求解后序遍历序列。2.没必要保存,在Push和Pop的过程中暗含了一些顺序信息。新建栈s。 当中序遍历Push时,说明在访问左子树,这时候我们把节点放入堆栈,并设置标签0,表示在访问左子树的过程中。当中序遍历Pop时,说明是左子树访问完毕返回的情况,我们并不真的pop s的元素,而是把s的栈顶元素设置为1,表示现在这个节点在中序遍历中已出栈,在访问右孩子的过程中。在设置栈顶元素为1之前要先pop掉所有栈顶为1的元素,这些元素已经是确定的后序遍历序列。输入为Push: 那么往s里面push,同时标记0输入为Pop:  那么先从堆栈s里面pop出标记为1的节点,从栈顶开始,到标记为0结束,同时输出。再把栈顶元素设置为1,表示要访问栈顶元素的右孩子。 **/ ST s;   //定义栈 int main(){char str[10];int t, n, ans[MAX], j=0;cin >> n;s.top = 0;   //代表栈中有0个元素 for(int i = 0; i < MAX; i++){s.flag[i] = 0;}for(int i = 0;i < 2*n; i++){cin >> str;if(strcmp(str,"Push") == 0){ //直接push cin >> t;s.data[s.top] = t;s.flag[s.top++] = 0;}else{ //输入的是pop //弹出栈顶标记为1的元素 while(s.top!=0){if(s.flag[s.top-1] == 1)ans[j++] = s.data[--s.top];elsebreak;}s.flag[s.top-1] = 1; //栈顶元素设置为1表示继续访问栈顶的右孩子。 }}while(s.top!=0) //栈中还有元素未出栈,依次出栈 ans[j++] = s.data[--s.top];for(int i=0;i<n;i++){if(i) printf(" ");printf("%d",ans[i]);} return 0;} 

算法2:
# include <stdio.h># include <string.h># include <iostream># include <stack># define MAX 60using namespace std;stack<int> s;void build(int n,char *s1,char* s2,char *s){if(n<=0) //没有节点要转换 return;int p=strchr(s2,s1[0]) - s2; //寻找s1[0]在s2中的下标build(p,s1+1,s2,s);build(n-p-1,s1+p+1,s2+p+1,s+p); //递归求右边n-p-1个节点s[n-1]=s1[0]; }int main(){char str[5];int s1[MAX],s2[MAX];int j1=0,j2=0,t,n;cin >> n;for(int i=0;i<2*n;i++){cin>>str;if(strcmp(str,"Push") == 0){cin>>t;s.push(t);s1[j1++] = t;}else{s2[j2++]=s.top();s.pop();}}char str1[MAX],str2[MAX],ans[MAX];for(int i=0;i<n;i++){str1[i] = s1[i]+'0';str2[i] = s2[i]+'0';}build(n,str1,str2,ans);ans[n]='\0';for(int i=0;i<n;i++){if(i) printf(" ");printf("%c",ans[i]);}printf("\n");return 0;} 
其中算法2在PAT的提交测试中,N=30,复杂组合,测试点5没有通过。留待后序研究,或者有知道原因的也可以联系我。





0 0
原创粉丝点击