PAT 1020 Tree Traversals[二叉树遍历]

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

题目大意:在二叉树中,其关键字是互不相通的正整数,给出其后根遍历(postorder)和中根遍历(inorder ),要求给出其层次遍历的顺序。

//其实没太做过二叉树的题目。果断放弃,查答案。代码来自:https://www.liuchuo.net/archives/2100

//不一定根节点就是n。

 //因为后根遍历中最后一个节点一定是根节点。

#include <iostream>
#include <vector>
#include<stdio.h>
using namespace std;
vector<int> post, in, level(100000, -1);//level是一个size为100000,初始化为-1
//因为N<=30,层数为30的,最多有2^30-1个节点。这好像也放不开啊。。
//root指向当前遍历段的根节点,开始下标(指向中根遍历),结束下标(指向中根遍历),层次遍历的下标。
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++;//while循环在中根遍历中找到根。

    //后根遍历中最后一个点一定是整棵树的根,从而分为左子树与右子树。
    level[index] = post[root];//当前层次遍历就是根节点。
    pre(root - 1 - end + i, start, i - 1, 2 * index + 1);
    //遍历左子树,index中存放的是层次遍历的结果。
    pre(root - 1, i + 1, end, 2 * index + 2);
    //遍历右子树,根据二叉树的存储特性,左子树是2*当前+1,右子树是2*当前+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) {//index可能是-1,表示那个节点为空。
            if (cnt != 0) printf(" ");
            printf("%d", level[i]);
            cnt++;
        }
        if (cnt == n) break;
    }
    return 0;
}

//另有中后遍历转前序遍历代码:

#include <cstdio>
using namespace std;
int post[] = {3, 4, 2, 6, 5, 1};
int in[] = {3, 2, 4, 1, 6, 5};
void pre(int root, int start, int end) {
    if(start > end) return ;
    int i = start;
    while(i < end && in[i] != post[root]) i++;//在中序遍历中找到根节点
    printf("%d ", post[root]);//打印根节点
    pre(root - 1 - end + i, start, i - 1);//遍历
    pre(root - 1, i + 1, end);
}

int main() {
    pre(5, 0, 5);
    return 0;
}

 

//感觉不要更牛一点。🐮 

 

posted @ 2018-08-06 14:57  lypbendlf  阅读(188)  评论(0编辑  收藏  举报