A1020 Tree Traversals (25 分)

因为晴神上有模板,所以直接水过了。

 

思路是先确定根结点,再确定左子树和右子树。确定根结点用前序、后序或层序,这些都是用来确定根结点的;下一步就是在中序序列中找到根结点的坐标位置,通过这个坐标确定左子树长度从而确定左子树和右子树。

 

需要注意的是申请结点空间是在  node_t *create() 函数里面申请的,也就是建树过程是在一步步递归  node_t *create() 函数实现的。

 

之后建完树就是实现一个层序遍历即可,层序遍历其实就是 BFS(),直接用之前总结的模板非常轻松

 

(因为水了一题,描述比较少,就直接贴代码凑数了 :-| )

#include <iostream>
#include <queue>
using namespace std;

const int maxn = 30;
struct node_t {
    int data;
    node_t *left;
    node_t *right;
};
int arr_post[maxn], arr_in[maxn];

node_t *create(int postL, int postR, int inL, int inR) {
    /* 递归边界 */
    if (postL > postR)    return NULL;

    /* 递归式 */
    node_t *root = new node_t;
    root->data = arr_post[postR];
    int k;
    for (k = 0; k < inR; ++k)//找到中序的根
        if (arr_post[postR] == arr_in[k])    break;
    int left_num = k - inL;//关键:算出左子树长度

    root->left = create(postL, postL + left_num - 1, inL, k - 1);
    root->right = create(postL + left_num, postR - 1, k + 1, inR);

    return root;
}

void level_traversal(node_t *t) {//类似 BFS() 遍历
    /* 起点入队 */
    queue<node_t *> q;//队列用结点指针类型比较方便
    q.push(t);
    while (!q.empty()) {
        /* 访问队头元素 */
        node_t *top =q.front();
        q.pop();

        if (top == t)    cout << top->data;
        else    cout << " " << top->data;
        /* 遍历队头元素的下一 "广度" 所有元素 */
        if (top->left)    q.push(top->left);
        if (top->right)    q.push(top->right);
    }
}

int main() {
    int n;

    /* 1. 输入 */
    cin >> n;
    for (int i = 0; i < n; ++i)    cin >> arr_post[i];
    for (int i = 0; i < n; ++i)    cin >> arr_in[i];

    /* 2. 主逻辑 */
    node_t *tree = create(0, n - 1, 0, n - 1);
    level_traversal(tree);

    return 0;
}

 

posted @ 2021-02-18 22:52  幼麟  阅读(71)  评论(0编辑  收藏  举报