[PAT解题报告] Tree Traversals

给定二叉树的后序和中序遍历,返回它的层序遍历。
分析: (1) 先还原二叉树。 因为节点数很少,我们可以用一个大的全局数组代替指针变量——当然每个节点的左右孩子还是指针变量,只不过它们的值指向大数组里的元素,而不是真正自己从堆里开辟的空间。还原可以递归进行。
后序遍历序列最后一个字符x是根节点  (R)x
中序遍历找到对应的x (A)x(B), 它被切分为(A)、(B)两部分,分别对应左右子树。从后序遍历序列的(R)中切分出(A)和(B)那么长的两段,对应于左右子树的后序遍历序列。然后递归还原左右子树即可。
还原出二叉树,做层序遍历时,只需要进行bfs就可以了。

代码:
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
using namespace std;

struct node {
node *left;
node *right;
int x;
};

node a[100];
int m,po[100],in[100];

node* make(int *po, int *in, int length) {
    if (length == 0) {
        return 0;
    }
    node *root = &a[m++];
    int i;
    for (i = 0; in[i] != po[length - 1]; ++i)
    ;
    root->x = in[i];
    root->left = make(po, in, i);
    root->right = make(po + i, in + i + 1, length - 1 - i);
    return root;
}
    
        


int main() {
int n;
    scanf("%d",&n);
    for (int i = 0; i < n; ++i) {
        scanf("%d",po + i);
    }
    for (int i = 0; i < n; ++i) {
        scanf("%d",in + i);
    }
    node *root = make(po, in, n);
    if (root) {
        bool have = false;
        queue<node *> q;
        q.push(root);
        node *last = root;
        while (!q.empty()) {
            bool out = false;
            node *next;
            while (!out) {
                node *temp = q.front();
                q.pop();
                if (temp == last) {
                    out = true;
                }
                if (temp->left) {
                    q.push(next = temp->left);
                }
                if (temp->right) {
                    q.push(next = temp->right);
                }
                if (have) {
                    putchar(' ');
                }
                else {
                    have = true;
                }
                printf("%d",temp->x);

            }
            last = next;
        }
    }
    puts("");
    return 0;
}
    

原题链接: http://www.patest.cn/contests/pat-a-practise/1020


全部评论
你好,我有个问题没能解决,我用了柳神的代码 #include <iostream> #include <vector> using namespace std; vector<int> post, in, level(100000, -1); void pre(int root, int start, int end, int index) { if(start > end) return ; int i = start; while(i < end && in[i] != post[root]) i++; level[index] = post[root]; pre(root - 1 - end + i, start, i - 1, 2 * index + 1); pre(root - 1, i + 1, end, 2 * index + 2); } int main() { int n, cnt = 0; scanf("%d", &n); post.resize(n); in.resize(n); for(int i = 0; i < n; i++) scanf("%d", &post[i]); for(int i = 0; i < n; i++) scanf("%d", &in[i]); pre(n-1, 0, n-1, 0); for(int i = 0; i < level.size(); i++) { if (level[i] != -1) { if (cnt != 0) printf(" "); printf("%d", level[i]); cnt++; } if (cnt == n) break; } return 0; } 大概是长的这样的,index的意思表示了当前的根结点在二叉树中所对应的下标,但是题目不是要求N<=30吗,如果这样算的话,2^30远大于代码里给的范围100000,但也能AC了,为什么会这样?按理说不是不满足边界条件吗
点赞 回复 分享
发布于 2018-11-02 20:49

相关推荐

01-14 19:01
吉首大学 Java
黑皮白袜臭脚体育生:加个项目吧,一般需要两个项目一业务一轮子呢,简历统一按使用了什么技术实现了什么功能解决了什么问题或提升了什么性能指标来写
点赞 评论 收藏
分享
做人要有梦想dji:最新工位查看图片
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务