给出中序和按层遍历,求该树的先序遍历,后序遍历,叶子结点。

发布时间 2023-12-24 18:26:56作者: potential-star

一切的核心是怎么利用中序和按层遍历构建二叉树?

1.优化空间很大,可以提前预处理记录每个数对应的位置,还可以vis数组记录这个点是不是已经作为根了。

2.我们考虑到每次找到当前中序要处理区间,里面的数记为集合mid,我们从前到后看层序遍历中的哪个数最先出现在mid中。那么这个数就是当前中序处理区间的根,这个新根的左边是左子树,右边是右子树,我们可以递归处理。

3.对于叶子节点,就是当他作为根的时候,没有左右节点,也就无法进行进一步深搜,flag记一下就可以了。

#include<stdio.h>
#include<vector>
#include<map>
#include<algorithm>
#include <algorithm>
#include <iostream>
#include<string>
using namespace std;

vector<int> InOrder, LevelOrder;
vector<int>ans;
vector<int>ans1,ans2;
void getPreOder(int l1, int r1, int l2, int r2) {
    int i, j;
    //l1,r1_inorder
    //l2,r2_levelorder
    //在中序中找到层序遍历当前的根节点
    for(i = l2; i <= r2; i++) {
        bool flag = false;
        for(j = l1; j <= r1; j++) {
            if(LevelOrder[i] == InOrder[j]) {
               // cout << LevelOrder[i]<<" ";
               ans1.push_back(LevelOrder[i]);
                flag = true;
                break;
            }
        }
        if(flag) break;
    }
    bool flag=false;
    if(j > l1) {getPreOder(l1, j - 1, 0, r2);flag=true;}
    if(j < r1) {getPreOder(j + 1, r1, 0, r2);flag=true;}
    if(!flag)ans.push_back(LevelOrder[i]);
}

// 递归构造后序遍历字符串
void getPostOrder(int l1, int r1, int l2, int r2) {
    int i, j;
    for(i = l2; i <= r2; i++) {
        bool flag = false;
        // 在中序遍历中找到当前层次遍历结点对应的位置
        for(j = l1; j <= r1; j++) {
            if(LevelOrder[i] == InOrder[j]) {
                flag = true;
                break;
            }
        }
        if(flag) break;
    }
   // cerr<<InOrder[j]<<endl;
    // 递归处理左子树
    if(j > l1) getPostOrder(l1, j - 1, 0, r2);
    // 递归处理右子树
    if(j < r1) getPostOrder(j + 1, r1, 0, r2);
    // 输出当前根节点的值
     ans2.push_back(InOrder[j]);
    //cout << InOrder[j]<<" ";
}

int main() {
   
    int n;
    cin>>n;
 // 读入层次遍历的字符串
      for(int i=0;i<n;i++){
      int x;cin>>x;
      LevelOrder.push_back(x);
      }
      //中序遍历
       for(int i=0;i<n;i++){
      int x;cin>>x;
      InOrder.push_back(x);
      }
    // 调用 getPostOrder 函数并传入整棵树的中序遍历区间和层次遍历区间
    getPreOder(0, InOrder.size() - 1, 0, LevelOrder.size() - 1);
    //cout<<endl;
    getPostOrder(0, InOrder.size() - 1, 0, LevelOrder.size() - 1);
    //cout<<endl;
for(auto x:ans)cout<<x<<" ";cout<<endl;
for(auto x:ans1)cout<<x<<" ";cout<<endl;
for(auto x:ans2)cout<<x<<" ";cout<<endl;
    return 0;
}