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;
}