PAT-A 1127题解
题目链接:
https://pintia.cn/problem-sets/994805342720868352/problems/994805349394006016
题意分析
给定后序遍历和中序遍历的序列,要求非正常层序遍历的输出(先左后右边,再右边往左边,接着从左往右…………以此类推)
算法分析
这道题要解决两个问题:
- 怎么把这个二叉树构建出来
- 怎么交替的按照从右往左和从左往右层序遍历。
首先这个构建二叉树的算法和平时我们用到的差不了太多。代码如下:
node* create_tree(int inL,int inR,int postR){//postR表示的是postorder的根节点的下标
if(inL > inR) {
return NULL;
}
node* root = new node;
root->val = post[postR];//没有欲望
int in_root_pos = pos_map[post[postR]];
int right_num = inR-in_root_pos;
root->lc = create_tree(inL,in_root_pos-1,postR-right_num-1);
root->rc = create_tree(in_root_pos+1,inR,postR-1);
return root;
}
当然要注意,无论是先序还是后续也好,都要以根节点为研究对象,看一个方向。比如先序遍历,只要找到了根节点,那么它的子树的结点就一定在它的右边,而后续遍历则相反,一定在它的左边。这一点要注意。
对于问题二,既然要交替输出左右、右左这样的顺序,我们想到了栈这个FILO数据结构。假设我们构造两个栈,先把结点放进去,然后把他的子结点都放到另一个栈里面。再从另一个栈里不断地把里面的元素出栈,出栈后把他们的左右儿子放到另一个栈里面,如此循环往复,直到所有元素都被清空。
完整代码
#include<unordered_map>
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
const int MAX_N = 32;
int post[MAX_N],in[MAX_N];
unordered_map<int,int> pos_map;
int n;
int count = 0;
struct node
{
node* lc,*rc;
int val;
};
node* create_tree(int inL,int inR,int postR){//postR表示的是postorder的根节点的下标
if(inL > inR) {
return NULL;
}
node* root = new node;
root->val = post[postR];//没有欲望
int in_root_pos = pos_map[post[postR]];
int right_num = inR-in_root_pos;
root->lc = create_tree(inL,in_root_pos-1,postR-right_num-1);
root->rc = create_tree(in_root_pos+1,inR,postR-1);
return root;
}
void print(node *root){
stack<node*> s_left,s_right;
int cnt = 0;
s_left.push(root);
while (s_left.size() > 0 || s_right.size() > 0)
{
if(cnt%2==0){
while (s_left.size())
{
node* now = s_left.top();
cout<<now->val;
count++;
if(count == n){
cout<<endl;
}
else cout<<" ";
if(now->rc!=NULL){
s_right.push(now->rc);
}
if(now->lc!=NULL){
s_right.push(now->lc);
}
s_left.pop();
}
}
else
{
while (s_right.size())
{
node* now = s_right.top();
cout<<now->val;
count++;
if(count == n){
cout<<endl;
}
else cout<<" ";
if(now->lc != NULL){
s_left.push(now->lc);
}
if(now->rc != NULL){
s_left.push(now->rc);
}
s_right.pop();
}
}
cnt++;
}
}
void postOrder(node* root){
if(root == NULL){
return;
}
postOrder(root->lc);
postOrder(root->rc);
cout<<root->val<<" ";
}
int main(){
cin>>n;
for(int i = 1;i<= n;i++){
cin>>in[i];
pos_map[in[i]] = i;
}
for(int i =1;i<= n;i++){
cin>>post[i];
}
node* root = create_tree(1,n,n);
//postOrder(root1);
print(root);
system("pause");
return 0;
}