根据前序(后序)和中序序列构建二叉树

题目:输入二叉树的前序遍历和中序遍历序列,重构其二叉树,假设输入的数字都是不重复的。
例如前序序列是 {1,2,4,7,3,5,6,8},中序序列是{4,7,2,1,5,3,8,6}。
分析如下图所示:
这里写图片描述

算法步骤:

  1. 前序序列pre的第一个元素即根节点。
  2. 遍历中序序列mid,找到的根节点,得到左子树的大小left_size。
  3. 左子树的中序序列为mid[0,left_size ),右子树的中序序列为mid[left_size+1, mid.size)
  4. 左子树的前序序列为pre[1,left_size ),右子树的前序序列为pre[left_size+1, pre.size)

代码如下(LeetCode-106):

TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
  if (pre.size() == 0 || vin.size() == 0) {
    return nullptr;
  }
  int root_val = pre[0];
  TreeNode* root = new TreeNode(root_val);
  int left_size = 0;
  for (int i = 0; i < vin.size(); ++i) {
    if (vin[i] == root_val) {
      left_size = i;
      break;
    }
  }
  vector<int> left_vin;
  left_vin.assign(vin.begin(), vin.begin() + left_size);
  vector<int> right_vin;
  right_vin.assign(vin.begin() + left_size + 1, vin.end());
  vector<int> left_pre;
  left_pre.assign(pre.begin() + 1, pre.begin() + 1 + left_size);
  vector<int> right_pre;
  right_pre.assign(pre.begin() + 1 + left_size, pre.end());

  root->left = reConstructBinaryTree(left_pre, left_vin);
  root->right = reConstructBinaryTree(right_pre, right_vin);
  return root;
}


根据先序和中序确定二叉树并按层次遍历输出:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;

const int N = 100010;

int n, pre[N], mid[N], last[N];
typedef struct tree{
    int num;
    struct tree *left, *right;
}*Tree, TreeNode;

Tree build(int pre[], int mid[], int size)
{
    if(size <= 0)   return NULL;
    Tree t = new TreeNode;
    int k, root;    //root表示根节点的值,k表示根节点的位置(下标从0开始)
    root = pre[0];  //先序序列的第一个元素是根节点
    for(int i = 0; i < size; i ++ ) //查找根节点在中序序列的位置
        if(mid[i] == root)
        {
            k = i;
            break;
        }
    t->num = root;
    t->left = build(pre + 1, mid, k);
    t->right = build(pre + k + 1, mid + k + 1, size - k - 1);
    return t;
}

void levelPrint(Tree &t)
{
    if(t == NULL)   return ;
    queue<Tree> q;
    q.push(t);
    while(q.size())
    {
        auto s = q.front();
        q.pop();
        cout << s->num << " ";
        if(s->left) q.push(s->left);
        if(s->right) q.push(s->right);
    }
}

int main()
{
    cin >> n;
    //输入先序和中序序列
    for(int i = 0; i < n; i ++ )    cin >> pre[i];
    for(int i = 0; i < n; i ++ )    cin >> mid[i];
    Tree t = build(pre, mid, n);
    levelPrint(t);
    
    return 0;
}

根据后序和中序确定二叉树并按层次遍历输出:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;

const int N = 100010;

int n, pre[N], mid[N], last[N];
typedef struct tree{
    int num;
    struct tree *left, *right;
}*Tree, TreeNode;

Tree build(int last[], int mid[], int size)
{
    if(size <= 0)   return NULL;
    Tree t = new TreeNode;
    int k, root;    //root表示根节点的值,k表示根节点的位置(下标从0开始)
    root = last[size - 1];  //后序序列的最后一个元素是根节点
    for(int i = 0; i < size; i ++ ) //查找根节点在中序序列的位置
        if(mid[i] == root)
        {
            k = i;
            break;
        }
    t->num = root;
    t->left = build(last, mid, k);
    t->right = build(last + k, mid + k + 1, size - k - 1);
    return t;
}

void levelPrint(Tree &t)
{
    if(t == NULL)   return ;
    queue<Tree> q;
    q.push(t);
    while(q.size())
    {
        auto s = q.front();
        q.pop();
        cout << s->num << " ";
        if(s->left) q.push(s->left);
        if(s->right) q.push(s->right);
    }
}

int main()
{
    cin >> n;
    //输入后序和中序序列
    for(int i = 0; i < n; i ++ )    cin >> last[i];
    for(int i = 0; i < n; i ++ )    cin >> mid[i];
    Tree t = build(last, mid, n);
    levelPrint(t);
    
    return 0;
}

posted @   光風霽月  阅读(147)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示