首页 > 其他分享 >根据前序遍历和中序遍历构造二叉树

根据前序遍历和中序遍历构造二叉树

时间:2022-11-07 09:14:07浏览次数:64  
标签:遍历 中序 pos 二叉树 l0 l1 前序

对于一个二叉树,如果我们我们知道他的前序遍历和中序遍历,那就可以直接构造还原出完整的二叉树。

举例:现在有一个二叉树,前序遍历是ABDECFG,中序遍历是DBEACGF。如何确定这个树的形态?

首先前序遍历的第一个字母是根,所以确定A是根,而在中序遍历里,我们找到了A的下标为3,把中序遍历分成xxxAxxx两部分,所以A的左子树大小为3.右子树大小也是3。回到前序遍历,从A往后属3个就是左子树的前序遍历,再往后数3个就是右子树的前序遍历。

示意图

构造二叉树的第一步

这样我们就构造出第一个点。以preOrder[1..3]作为新的前序,inOrder[0..2]作为新的中序,就可以构造出A的左子树(右也同理)。

image

直到一个子树只剩下一个点,我们就构造完成了。

最后的二叉树

这样来看,我们会把整个树里的每个点都走一次,而每次如何查找前序的第一个点在中序里的下标呢?每次查找要遍历一遍,太慢了。可以开一个哈希表,每次直接查询节点对应的下标,这样总时间就是O(N)的。

struct node{
    node *ls, *rs;
    char name;
    node():name(0), ls(0), rs(0) {}
}*root(new node);

string preOrder, inOrder;
unordered_map<char, int> map_inOrder;

// generate的含义是,取 preOrder[l0..r0] 为前序,inOrder[l1..r1] 为中序构造一个 p 上的子树
void generate(int l0, int r0, int l1, int r1, node* p) {
    if (l0 > r0) return; // 已经到头了,不再往下构造
    p->name = preOrder[l0]; // 前序的第一个点 就是当前根节点

    int pos = map_inOrder[p->name]; 
    generate(l0+1, pos-l1+l0, l1, pos-1, p->ls=new node); 
    // 左子树的的中序从 l1 开始,pos-1结束,长度为 pos-l1, 所以计算出左子树的前序遍历从 l0+1 到 pos-l1+l0

    generate(pos-l1+l0+1, r0, pos+1, r1, p->rs=new node); // 右子树同理
}

main() {
    cin >> preOrder >> inOrder;
    int len = preOrder.size();

    for (int i=0; i<len; i++) map_inOrder[inOrder[i]] = i; //此处记录每个节点在中序遍历的下标
    generate(0, len-1, 0, len-1, root); // 左闭右闭
}

那么给定一个树的前序遍历和后序遍历,能不能构造出这个树呢?一般是不行的,反例很好找。就拿上面那个树来说,已知前序ABDECFG,后序DEBGFCA, 上面的树是一个答案,把 G 放到 F 的右边又是一个答案,一个前序遍历和一个后序遍历可以对应很多二叉树。

标签:遍历,中序,pos,二叉树,l0,l1,前序
From: https://www.cnblogs.com/ofnoname/p/16864200.html

相关文章

  • 297. 二叉树的序列化与反序列化
    序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得......
  • 不知道为什么递归失败 二叉树 演我?
    不知道为什么不能够递归搞明白了再更啊哈哈哈怎么突然就行了准备截一张失败的图来着然后突然就出来了也不知道之前为什么失败  非递归的今天晚上应该写不出来了......
  • #yyds干货盘点# LeetCode 腾讯精选练习 50 题:二叉树中的最大路径和
    题目:路径被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中至多出现一次。该路径至少包含一个节点,且不一定经过根节......
  • 二叉树中查找后继节点问题
    二叉树中查找后继节点问题作者:Grey原文地址:博客园:二叉树中查找后继节点问题CSDN:二叉树中查找后继节点问题题目描述给定一个二叉查找树,以及一个节点,求该节点在中序遍......
  • 236. 二叉树的最近公共祖先
    给定一个二叉树,找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树T的两个节点p、q,最近公共祖先表示为一个节点x,满足x是p、q......
  • 套汇问题 Python实现,算法设计,DFS深度遍历
    #P67#套汇问题可以理解为一个有向图找出环的问题,#要想有盈利,需要所有的汇率乘积大于1#在贪心条件下,找到一个环路径上的乘积大于1就有套汇的可能性"""#输入一......
  • 114. 二叉树展开为链表
    给你二叉树的根结点 root ,请你将它展开为一个单链表:展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。展......
  • 数据结构 图的遍历(广度优先遍历、深度优先遍历)
    8.6、图的广度优先遍历找到与顶点相邻的所有顶点,标记哪些顶点被访问过需要一个辅助队列#include<stdio.h>#include<stdlib.h>#include<math.h>#defineMaxSiz......
  • 二叉树的最大宽度系列问题
    二叉树的最大宽度系列问题作者:Grey原文地址:博客园:二叉树的最大宽度系列问题CSDN:二叉树的最大宽度系列问题求树的最大宽度题目描述给你一棵二叉树的根节点root,返......
  • 105. 从前序与中序遍历序列构造二叉树
    给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。示例1:  输入:pre......