美文网首页IOS个人开发
如何根据先序遍历和中序遍历还原二叉树

如何根据先序遍历和中序遍历还原二叉树

作者: 小幸运Q | 来源:发表于2018-08-18 20:58 被阅读153次

先序遍历序列:1 2 3 4 5 6 8 9 7
中序遍历序列:3 2 4 1 8 6 9 5 7 
image.png
  1. 利用在中序数组中的
    新左/右子树长度:abs(middle-newmiddle)
    总长度:RL-LL/RR-RL
    计算出在前序数组中新的LL,LR,RL,RR的对应位置
    记得将newmiddle传给下一次递归作为它的middle

    image.png
  2. 当LL==LR/RR==RL时要单独处理,因为我的这种计算方式无法处理==的情况

示例代码:

#include<iostream>
#include<cstdio>
using namespace std;
#define N 1000
int counts=0;
int preorder[N]={0};
int inorder[N]={0};
typedef struct Node{
  int num;
  Node*left;
  Node*right;
  Node(){
    left=NULL;
    right=NULL;
    num=0;
  }
}Node;
// 如果有题目需求可以改成map查找
int search(int target){
  int i;
  for(i=0;i<counts;i++){
    if(inorder[i]==target){
      return i;
    }
  }
}
// LL,LR,RL,RR是在preorder中的标记位。 middle是上一轮的newmiddle在inorder中的标记位。
void built(Node*&root,int LL,int LR,int middle,int RL,int RR){
  cout<<"\nmiddle:"<<middle<<endl;
  cout<<"LL:"<<LL<<"  LR:"<<LR<<endl;
  cout<<"Rl:"<<RL<<"  RR:"<<RR<<endl;
  if(LL==LR){
    // cout<<"end in:"<<LL<<endl;
    Node*node=new Node();
    node->num=preorder[LL];
    root->left=node;
    // return;
    // 不要立即返回,要不然后面的==的情况会被忽略
  }
  if(RL==RR){
    // cout<<"end in:"<<RR<<endl;
    Node*node=new Node();
    node->num=preorder[RL];
    root->right=node;
    // return;
  }
  if(LL<LR){
    Node*node=new Node();
    node->num=preorder[LL];
    root->left=node;
    int newmiddle=search(preorder[LL]);
    int rlength=(middle-newmiddle-1);
    int llength=(LR-LL)-rlength;
    built(root->left,LL+1,LL+llength,newmiddle,LR-(rlength-1),LR);
  }
  if(RL<RR){
    Node*node=new Node();
    node->num=preorder[RL];
    root->right=node;
    int newmiddle=search(preorder[RL]);
    int llength=(newmiddle-middle-1);
    int rlength=(RR-RL)-llength;
    built(root->right,RL+1,RL+llength,newmiddle,RR-(rlength-1),RR);
  }
}
void print(Node*root){
  if(root==NULL){
    return ;
  }
  print(root->left);
  print(root->right);
  cout<<root->num<<"->";
}
int main(){
  int i,j;
  cin>>counts;
  for(i=0;i<counts;i++){
    cin>>preorder[i];
  }
  for(i=0;i<counts;i++){
    cin>>inorder[i];
  }
  Node*root=NULL;
  Node*node=new Node();
  node->num=preorder[0];
  root=node;
  int middle=search(preorder[0]);
  //
  built(root,1,middle,middle,middle+1,counts-1);
  print(root);
}

/*
9
1 2 3 4 5 6 8 9 7
3 2 4 1 8 6 9 5 7
*/

相关文章

  • LeetCode 力扣 105. 从前序与中序遍历序列构造二叉树

    题目描述(中等难度) 根据二叉树的先序遍历和中序遍历还原二叉树。 解法一 递归 先序遍历的顺序是根节点,左子树,右...

  • 二叉树的遍历

    本节主要介绍如何根据二叉树的遍历序列还原二叉树 1.根据前序遍历序列ABCDEF和中序遍历序列CBAEDF如何判断...

  • 二叉树遍历算法

    二叉树遍历算法有4种,先序、中序、后序和层序遍历 先序遍历:先根、后左、再右中序遍历:先左、后根、再右后序遍历:先...

  • 重建二叉树与寻找下一个节点

    一、重建二叉树 题目:输入某二叉树的先序遍历和中序遍历的结果,请重建二叉树。假如输入的先序遍历和中序遍历的结果都不...

  • 由遍历序列恢复二叉树

    根据二叉树的定义,先序遍历是先访问根节点,然后再先序遍历左子树的,最后先序遍历右子树。因此,先序遍历序列中的第一个...

  • 二叉树的前序遍历、中序遍历、后序遍历、层次遍历

    二叉树的遍历方式主要有:先序遍历、中序遍历、后序遍历、层次遍历。先序、中序、后序其实指的是父节点被访问的次序。若在...

  • 数据结构与算法二叉树的遍历与线索二叉树以及森林

    1.二叉树的遍历先序遍历、中序遍历、后序遍历 2.层次遍历利用队列实现 3.由遍历序列构成二叉树先序、后序可以与众...

  • 要成功就做一百题-98

    题目名称 二叉树的中序遍历 描述 给定一个先序遍历的二叉树,打印出其中序(中根)遍历的结构。 解题思路 首先是根据...

  • Java 二叉树

    创建一个二叉树对象 build 一个二叉树 遍历 先序遍历 后序遍历 中序遍历 先序遍历的结果为:0 1 3...

  • 二叉树-遍历算法

    先序遍历 思路:先根节点->左子树->右子树;二叉树如下图: 先序遍历结果:ABDEGCFHI 中序遍历 思路:先...

网友评论

    本文标题:如何根据先序遍历和中序遍历还原二叉树

    本文链接:https://www.haomeiwen.com/subject/kkkabftx.html