PAT(甲级)1020 Tree Traversals (25point(s))

题目

题目链接

思路

给出后序和中序,重构二叉树;
这其实是一个递归的过程:依据后序序列的最后一位是根节点这一性质,每次我们取子序列的最后一位,注意这个子序列是一颗完整子树的后序;
然后去中序中找到这个元素,根据这个元素就可以把中序序列一分为二,左边是左子树,右边是右子树;
递归进行;
后序:[左子树元素,右子树元素,根节点]
中序:[左子树元素,根节点,右节点元素]

代码
#include <iostream>
#include <vector>
using namespace std;
vector<int> postOrder, inOrder, ans(100000+10, -1);
void pre(int root, int start, int end, int idx){
    if(start > end) return ;
    ans[idx] = postOrder[root];
    int i = start;
    while(i <= end && inOrder[i] != postOrder[root]) i++;
    pre(root - (end - i) - 1, start, i-1, 2 * idx);
    pre(root - 1, i + 1, end, 2 * idx + 1);
    return;
}
int main(){
    int cnt, test;
    scanf("%d", &cnt);
    postOrder.resize(cnt);
    inOrder.resize(cnt);
    for(int i=0; i<cnt; i++) scanf("%d", &postOrder[i]);
    for(int i=0; i<cnt; i++) scanf("%d", &inOrder[i]);
    pre(cnt-1, 0, cnt-1, 1);
    for(int i=1; i<ans.size(); i++){
        if(ans[i] != -1) {
            cout << ans[i];
            cnt--;
            if(cnt > 0) printf(" ");
            else break;
        }
    }
    return 0;
}
代码
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cstring>
#include <math.h>
using namespace std;
const int maxn = 35;
struct node {
     int data;
     node* left;
     node* right;
};
int pre[maxn], in[maxn], post[maxn];
int n, num = 0;//节点个数
//递归建树,返回根节点指针,参数分别是后序序列的左边界,右边界;中序序列的左边界,右边界
node* create(int postL, int postR, int inL, int inR){
     //递归结束的条件,后序序列的元素个数小于等于0
     if(postL > postR) return NULL;
     node* root = new node;//将要返回的这棵树的根节点指针
     root -> data = post[postR];
     int k = inL; //当前子树根节点在中序中所对应的下标
     while(k <= inR && post[postR] != in[k]) k ++;
     int num = k - inL;//左子树的元素个数
     root -> left = create(postL, postL + num - 1, inL, k - 1);
     root -> right = create(postL + num, postR - 1, k + 1, inR);
     return root;
}
void BFS(node* root){
     queue<node*> Q;
     Q.push(root);
     while(!Q.empty()){
          node* top = Q.front();
          Q.pop();
          printf("%d", top -> data);//输出节点
          num ++;
          if(num < n) printf(" ");
          if(top -> left != NULL) Q.push(top -> left);
          if(top -> right != NULL) Q.push(top -> right);
     }
}
int main()
{
     scanf("%d", &n);
     //读入后序和中序
     for(int i = 0; i < n; i ++) scanf("%d", &post[i]);
     for(int i = 0; i < n; i ++) scanf("%d", &in[i]);
     node* root = create(0, n - 1, 0, n - 1);
     BFS(root);
     system("pause");
     return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值