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

解题报告-PAT- Tree Traversals Again
Tree Traversals Again有两种解题思路:
1、在Push和Pop的过程中记录后序序列。
2、构造先序序列和中序序列,然后build后序序列。

PAT原题链接:https://www.patest.cn/contests/pat-a-practise/1086
下面给出两种算法:
算法1:
# include 
# include 
# include 
# define MAX 60

typedef 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];
				else
					break;
			}
			s.flag[s.top-1] = 1; //栈顶元素设置为1表示继续访问栈顶的右孩子。 
		}
	}
	while(s.top!=0) //栈中还有元素未出栈,依次出栈 
		ans[j++] = s.data[--s.top];
	
	for(int i=0;i

算法2:
# include 
# include 
# include 
# include 
# define MAX 60
using namespace std;

stack 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
其中算法2在PAT的提交测试中,N=30,复杂组合,测试点5没有通过。留待后序研究,或者有知道原因的也可以联系我。





你可能感兴趣的:(ACMer养成)