PAT-A 1020 Tree Traversals (25)(25 分)

https://pintia.cn/problem-sets/994805342720868352/problems/994805485033603072

1020 Tree Traversals (25)(25 分)

Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder and inorder traversal sequences, you are supposed to output the level order traversal sequence of the corresponding binary tree.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (<=30), the total number of nodes in the binary tree. The second line gives the postorder sequence and the third line gives the inorder sequence. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in one line the level order traversal sequence of the corresponding binary tree. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the end of the line.

Sample Input:

7
2 3 1 5 7 6 4
1 2 3 4 5 6 7

Sample Output:

4 1 6 3 5 7 2

思路及关键点:

方法1:使用传统的string串方法进行二叉树重建,可是cin>>string不能读入空格;

             于是使用getline(cin,str)可以读入string里面的空格;

             但是使用substr方法切分的时候,左子树、右子树的长度将相比于原来发生变化;

            于是手写一个trim(str)方法来过滤掉string字符串里的所有空格。自己测试时没有出现任何问题。

           但是此程序只通过了部分测试点,百思而不得其解,望各位巨佬尝试此方法时指点一二!

//后中定序。输出层次遍历序列 
#include <iostream>
#include <cstdio>
#include <queue> 
#include <string>
using namespace std;
struct node{
	char data;
	node* lchild;
	node* rchild;
};
int n;//总的节点个数 
int num=0;//已经输出的节点个数 
void LayOrder(node* root){
	queue<node*>q;
	q.push(root);
	while(!q.empty()){
		node* now=q.front();
		q.pop();
		printf("%c",now->data);
		num++; 
		if(num<n){
			printf(" ");
		}
		if(now->lchild!=NULL) q.push(now->lchild);
		if(now->rchild!=NULL) q.push(now->rchild);
	}
}

node* Create(string postorder,string inorder){
	node* root=NULL;
	if(postorder.size()>0){
		root=new node;
		int len=postorder.size();
		root->data=postorder[len-1];
		root->lchild=NULL;
		root->rchild=NULL;
		string post1,post2;
		string in1,in2;
		int index=inorder.find(postorder[len-1]);
		in1=inorder.substr(0,index);
		in2=inorder.substr(index+1,inorder.size()-index-1);
		post1=postorder.substr(0,index);
		post2=postorder.substr(index,postorder.size()-index-1);
		
		root->lchild=Create(post1,in1);
		root->rchild=Create(post2,in2);
	}
	return root;
}

void trim(string &s)//过滤掉string里的全部空格 
{
    int index = 0;
    if( !s.empty())
    {
        while( (index = s.find(' ',index)) != string::npos)
        {
            s.erase(index,1);
        }
    }

}
int main(int argc, char** argv) {
	string s1,s2;
	//int n;
	cin>>n;
	getchar();
	while(getline(cin,s1)&&getline(cin,s2)&&s1.size()==2*n-1&&s2.size()==2*n-1&&n<=30){
		//cout<<s1<<endl;
		//cout<<s2<<endl;
		trim(s1);//过滤掉string里的所有空格 
		trim(s2);
		//cout<<s1<<endl;
		//cout<<s2<<endl;
		node* root=Create(s1,s2);
		LayOrder(root);
		cout<<endl;
	} 
	return 0;
}

方法二:以下是用数组的方式重建二叉树的,25分

//后中定序,输出层次序列 
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std; 
const int nmax=40;
struct node{
	int data;
	node* lchild;
	node* rchild;
};
int pre[nmax],in[nmax],post[nmax];
int n;//节点总数 

node* Create(int pstL,int pstR,int inL,int inR){//后中定序 
	node* root=NULL;
	if(pstL>pstR){
		root=NULL;
		return root;
	} 
	else{
		root=new node;
		root->data=post[pstR];
		root->lchild=NULL;
		root->rchild=NULL;
		
		int k;
		for(k=inL;k<=inR;k++){//找到中根序列的分界点 
			if(in[k]==post[pstR]){
				break;
			}
		}
		int  numleft=k-inL;
		root->lchild=Create(pstL,pstL+numleft-1,inL,k-1);//创建左子树 
		root->rchild=Create(pstL+numleft,pstR-1,k+1,inR);//创建右子树 
		return root;
	}
}

int num=0;//已输出节点个数 
void LayOrder(node* root){
	queue<node*>q;
	q.push(root);
	while(!q.empty()){
		node* now=q.front();
		q.pop();
		printf("%d",now->data);//输出队首元素
		num++; 
		if(num<n){
			printf(" ");
		}
		if(now->lchild!=NULL) q.push(now->lchild);
		if(now->rchild!=NULL) q.push(now->rchild);
	}
}
int main(int argc, char** argv) {
	//int n;
	while(cin>>n){
		for(int i=0;i<n;i++){
			cin>>post[i]; 
		}
		for(int i=0;i<n;i++){
			cin>>in[i];
		}
		node* root=Create(0,n-1,0,n-1);
		LayOrder(root);
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值