• 1020. Tree Traversals


    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

    本题考查树的遍历, 给出后根遍历和中根遍历,可以确定一棵树, 最后使用层次遍历获取LevelOrder,思路如下:
    直接上例子, 题目给出后根遍历2 3 1 5 7 6 4, 中根遍历1 2 3 4 5 6 7
    后跟遍历可知, 4是整棵树的跟, 再看中跟遍历中4的位置,把整棵树分成1,2,3组成的左子树和5,6, 7组成的右子树, 同理, 后根遍历中也会分成2,3,1 和5,7,6两颗子树, 此时,后根2,3,1对应中根1 2 3, 后根5,7,6对应中跟5,6,7可继续递归求解,但是要注意判断特殊情况:

    • 确定根后, 发现根在中根遍历的最右边,那么此书右子树为空
    • 确定根后, 发现根在中根遍历的最左边,那么此书左子树为空
    #include <iostream>
    #include <queue>
    using namespace std;
    
    typedef struct
    {
        int value;
        int left;
        int right;
    } Node;
    
    Node node[32];
    int postOrder[32];//后跟遍历
    int midOrder[32];//中跟遍历
    int N;
    
    //递归函数, l1,r1表示后跟遍历的左界和右界
    //l2, r2表示中根遍历的左界和右界
    void f(int l1, int r1, int l2, int r2)
    {
        int root = postOrder[r1];
    
        if(l1 == r1)
        {
            node[root].left = node[root].right = -1;
            return;
        }
        //i记录根在midOrder的位置
        int i = 0;
        while(midOrder[i] != root) i++;
        int cntL = i - l2;  //cntL表示i左边有几个元素,用于分隔postOrder
    
        if(i == l2)//左子树为空情况
        {
            node[root].left = -1;
            node[root].right = postOrder[r1 - 1];
            f(l1 + cntL, r1 - 1, i + 1, r2);
            return;
        }
        if(i == r2)//右子树为空情况
        {
            node[root].right = -1;
            node[root].left = postOrder[r1 - 1];
            f(l1, l1 + cntL - 1, l2, i - 1);
            return;
        }
        //两边都不为空,先求解两根
        f(l1, l1 + cntL - 1, l2, i - 1);
        f(l1 + cntL, r1 - 1, i + 1, r2);
        
        //最后给根赋值
        node[root].left = postOrder[l1 + cntL - 1];
        node[root].right = postOrder[r1 - 1];
    
    }
    //层次遍历
    void bfs()
    {
        int root = postOrder[N - 1];
        queue<int> q;
        q.push(root);
        int first = 1;
        while(!q.empty())
        {
            int v = q.front();
            if(first)
            {
                first = 0;
                cout << v;
            }
            else
            {
                cout << " " << v;
            }
            q.pop();
            if(node[v].left != -1)
                q.push(node[v].left);
            if(node[v].right != -1)
                q.push(node[v].right);
        }
    }
    int main()
    {
        cin >> N;
    
        for(int i = 0; i < N; i++)
        {
            cin >> postOrder[i];
        }
        for(int i = 0; i < N; i++)
        {
            cin >> midOrder[i];
        }
    
        f(0, N - 1, 0, N - 1);
    
        bfs();
    
        return 0;
    }
    
  • 相关阅读:
    Java 介绍比较全面的一遍文章
    JSP页面中path和basepath的含义
    myeclipse2014 破解步骤
    word文档去掉复制过来的背景颜色
    String,创建对象问题
    使用Spring框架的好处(转帖)
    myeclipse中将整块的代码所选中的代码左右移动的快捷键
    点击关闭窗口时,弹出提醒的一个事件
    switch能使用的数据类型有6种
    观察者模式(设计模式_15)
  • 原文地址:https://www.cnblogs.com/princecoding/p/5840750.html
Copyright © 2020-2023  润新知