Bootstrap

【复旦大学历年机试题】2011-02(二叉树遍历)

在这里插入图片描述
题目:输入树的中序和后序排列,输出树的层次遍历。

输入样例
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7
输出样例:
4 1 6 3 5 7 2

题解:本题是二叉树遍历的一个综合考察,给定二叉树的中序与前序(或后序)遍历,求解二叉树的后序(或层次)遍历,可以归为一个大类。其解题方法都是先根据中序与前序(或后序)遍历重建二叉树,而后输出后序(或层次)遍历。因此本题步骤分为两步:
(1)重建二叉树:定义root为后序遍历中根结点的位置,left、right为中序遍历的左右边界,定义cur指针指向当前结点。定义一个变量index指向中序遍历中根节点的位置,根据根节点将树划分为左右子树,那么右子树的根结点为root-1,右子树右边界为right,右子树左边界为index+1,左子树根结点为root-right+index-1,左子树左边界为left,左子树右边界为index-1。
(2)层次遍历二叉树:对重建的二叉树进行层次遍历即可。

代码(C++)

#include <bits/stdc++.h>
using namespace std;

// 全局变量
vector<int> in,post,pre,level;  // 定义四种遍历顺序的数组

struct TreeNode{
    TreeNode* lchild;
    TreeNode* rchild;
    int val;
    TreeNode() : val(0), lchild(nullptr), rchild(nullptr) {}
    TreeNode(int x) : val(x), lchild(nullptr), rchild(nullptr) {}
};

void rebuild(int root, int left, int right, TreeNode* &cur){  //root为后序遍历中子树根结点的位置,left、right为中序遍历的左右边界
    int index;  // 定位root在中序遍历中的位置

    if(left > right)  return;  // 终止条件

    cur = new TreeNode(post[root]);  // 定义新结点
    for(index = left; index <= right; index++){
        if(in[index] == post[root]){  // 在中序遍历中找到了root,index就是其位置
            break;
        }
    }
    rebuild(root - right + index -1, left, index - 1, cur->lchild);
    rebuild(root - 1, index + 1, right, cur->rchild);
}

void levelOrder(TreeNode* root){
    TreeNode* cur;  // 指向当前结点
    queue<TreeNode*> que;  // 定义队列

    if(root)    que.push(root);  // 根结点入队
    while(!que.empty()){
        int size = que.size();
        for(int i = 0; i < size; i++){
            cur = que.front();
            que.pop();
            level.push_back(cur->val);
            if(cur->lchild)    que.push(cur->lchild);
            if(cur->rchild)    que.push(cur->rchild);
        }
    }
}

int main(){
    // 定义变量
    TreeNode* root;  //二叉树
    int n,cur;  //输入个数

    // 输入
    scanf("%d",&n);
    for(int i = 0; i < n; i++){  // 输入后序遍历
        scanf("%d",&cur);
        post.push_back(cur);
    }
    for(int i = 0; i < n; i++){  // 输入中序遍历
        scanf("%d",&cur);
        in.push_back(cur);
    }

    // 主体
    rebuild(n-1,0,n-1,root);
    levelOrder(root);

    // 输出
    for(int i = 0; i < n; i++){
        if(i < n-1){
            cout << level[i] << " ";
        }else{
            cout << level[i] << endl;
        }
    }

    return 0;
}

写在后面

这个专栏主要是我在刷题的过程中总结的一些笔记,因为我学的也很一般,如果有错误和不足之处,还望大家在评论区指出。希望能给大家的学习带来一点帮助,共同进步!!!

;