好不容易又到周五了,周末终于可以休息休息了。写这一篇随笔只是心血来潮,下午问了一位朋友PAT考的如何,顺便看一下他考的试题,里面有最后一道题,是关于给出中序遍历和后序遍历然后求一个层次遍历。等等,我找一下链接出来......

  1127. ZigZagging on a Tree (30):https://www.patest.cn/contests/pat-a-practise/1127

  突然想起以前学数据结构的时候如果给出一个中序遍历和一个后序遍历然后让你画出树的结构或求出先序遍历之类的题目,如果用笔来画,三下五除二能够一下子就画出来,但关于用语言编写出来却从来没有想过,真是惭愧,所以这篇随笔的内容思维可能比较简单低阶,请大家包涵。

  所以想试一下能不能写一写,加之最近在补习一些算法和数据结构之类的题目,可以作为一个练手的题目。想不到要动手之前理清一下构造的过程,最后却有些明朗的感觉,这也是我想写下这篇随笔的原因,虽然简单,但很有意义。好,说了这么多废话...下面开始:

  对于一棵树的中序遍历,根节点肯定处于遍历结果的中间(假设这棵树有左子树),后序遍历的时候根节点肯定是最后一个遍历的元素。所以可以轻易得到根在中序遍历中的位置,根据中序遍历的性质,以根为中点往后遍历到的元素就是这棵树的右子树元素,往前遍历到的就是这棵树的左子树元素。而后续遍历也是把这棵树的左子树全部遍历完整之后再来遍历右子树,因此在后续遍历中,左子树和右子树的元素也是有明显的界限。而对于根节点的左节点和右节点也是同样的道理。举个例子

                 

所以我们从最初的遍历顺序开始,找出后续遍历的最后一个元素在中序遍历中的位置,然后以这个位置为重点,往右的遍历元素为A,往左的遍历元素为B,根据A和B的长度可以确定在后续遍历中的遍历元素边界,对A和B进行上一步的操作,直到所有元素遍历完成。代码:

  1. Node *getRoot(int* inorder,int* postorder,int ix,int iy,int px,int py){
  2. Node *node = new Node(postorder[py]);
  3. int p = findElem(inorder,postorder[py],ix,iy);
  4. if(- != p){
  5. int lix,liy,lpx,lpy,rix,riy,rpx,rpy;
  6. if(p == iy)node->right = NULL;
  7. else{
  8. rix = p+;
  9. riy= iy;
  10. rpy = py-;
  11. rpx = rpy - (riy-rix);
  12. node->right = getRoot(inorder,postorder,rix,riy,rpx,rpy);
  13. }
  14. if(p == ix) node->left = NULL;
  15. else{
  16. lix = ix;
  17. liy = p -;
  18. lpx = px;
  19. lpy = px + (liy-lix);
  20. node->left = getRoot(inorder,postorder,lix,liy,lpx,lpy);
  21. }
  22.  
  23. return node;
  24. }else
  25. return NULL;
  26. }
  27. void MidTraverse(Node *root){
  28. if(NULL != root){
  29. cout<<root->val<<" ";
  30. MidTraverse(root->left);
  31. MidTraverse(root->right);
  32. }
  33. }
  34. int main(){
  35. int count;
  36. cin>>count;
  37. int *inorder = new int[count];
  38. int *postorder = new int[count];
  39. for(int i =;i<;i++){
  40. for(int j=;j<count;j++){
  41. int in;
  42. cin>>in;
  43. if(==i) inorder[j] = in;
  44. else postorder[j] = in;
  45. }
  46. }
  47. Node *root = getRoot(inorder,postorder,,count-,,count-);
  48. if(NULL !=root)
  49. MidTraverse(root);
  50. }

节点定义为:

  1. typedef struct _Node{
  2. int val;
  3. struct _Node *left,*right;
  4. _Node(int _val):val(_val),left(NULL),right(NULL){}
  5. }Node;

运行代码,最后结果在意料之内:

深圳的工作压力强行把市民的生活节奏拉的飞快,上了一周的班心绪有些烦躁,下班出了公司的门却意外地迎来了树叶和泥土的味道,是一场雨清澈了整片空气。

根据 中序遍历 和 后序遍历构造树(Presentation)(C++)的更多相关文章

  1. lintcode: 中序遍历和后序遍历树构造二叉树

    题目 中序遍历和后序遍历树构造二叉树 根据中序遍历和后序遍历树构造二叉树 样例 给出树的中序遍历: [1,2,3] 和后序遍历: [1,3,2] 返回如下的树: 2 /  \ 1    3 注意 你可 ...

  2. java编写二叉树以及前序遍历、中序遍历和后序遍历 .

    /** * 实现二叉树的创建.前序遍历.中序遍历和后序遍历 **/ package DataStructure; /** * Copyright 2014 by Ruiqin Sun * All ri ...

  3. python数据结构之树和二叉树(先序遍历、中序遍历和后序遍历)

    python数据结构之树和二叉树(先序遍历.中序遍历和后序遍历) 树 树是\(n\)(\(n\ge 0\))个结点的有限集.在任意一棵非空树中,有且只有一个根结点. 二叉树是有限个元素的集合,该集合或 ...

  4. TZOJ 3209 后序遍历(已知中序前序求后序)

    描述 在数据结构中,遍历是二叉树最重要的操作之一.所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问. 这里给出三种遍历算法. 1.中序遍历的递归算法定义:  ...

  5. LintCode2016年8月8日算法比赛----中序遍历和后序遍历构造二叉树

    中序遍历和后序遍历构造二叉树 题目描述 根据中序遍历和后序遍历构造二叉树 注意事项 你可以假设树中不存在相同数值的节点 样例 给出树的中序遍历: [1,2,3] 和后序遍历: [1,3,2] 返回如下 ...

  6. 数据结构实习 - problem K 用前序中序建立二叉树并以层序遍历和后序遍历输出

    用前序中序建立二叉树并以层序遍历和后序遍历输出 writer:pprp 实现过程主要是通过递归,进行分解得到结果 代码如下: #include <iostream> #include &l ...

  7. LintCode-72.中序遍历和后序遍历树构造二叉树

    中序遍历和后序遍历树构造二叉树 根据中序遍历和后序遍历树构造二叉树 注意事项 你可以假设树中不存在相同数值的节点 样例 给出树的中序遍历: [1,2,3] 和后序遍历: [1,3,2] 返回如下的树: ...

  8. 小小c#算法题 - 11 - 二叉树的构造及先序遍历、中序遍历、后序遍历

    在上一篇文章 小小c#算法题 - 10 - 求树的深度中,用到了树的数据结构,树型结构是一类重要的非线性数据结构,树是以分支关系定义的层次结构,是n(n>=0)个结点的有限集.但在那篇文章中,只 ...

  9. 数据结构学习-BST二叉查找树 : 插入、删除、中序遍历、前序遍历、后序遍历、广度遍历、绘图

    二叉查找树(Binary Search Tree) 是一种树形的存储数据的结构 如图所示,它具有的特点是: 1.具有一个根节点 2.每个节点可能有0.1.2个分支 3.对于某个节点,他的左分支小于自身 ...

随机推荐

  1. Oracle 子程序参数模式,IN,OUT,IN OUT

    IN :用于传入参数. 在调用过程的时候,实参传到该过程中. 在过程内部,形参只读且不能更改. 在过程执行完毕,返回调用环境时候,实参到的值也不会改变 --带IN参数的过程,赋值. create or ...

  2. Flex读取txt文件中的内容报错

    Flex读取txt文件中的内容 1.具体错误如下 2.错误原因 读取文件不存在 var file:File = new File(File.applicationDirectory.nativePat ...

  3. VMware vSphere学习整理

    知识点整理 内存选择 一般来说,每个虚拟机需要的内存在1~4GB甚至更多,还要为VMware ESXi预留一部分内存 2个6核的2U服务器配置64GB内存,4个6核或8核心的4U服务器配置128GB或 ...

  4. CF374 Maxim and Array

    贪心 如果有0先变成非0 如果负数的个数 应该变为偶数 之后就是每次将绝对值最小的值加K #include<bits/stdc++.h> using namespace std; cons ...

  5. SonarQube和Maven的集成

    1.1. SonarQube简介 SonarQube是一款免费用于代码质量管理的开源平台,用于管理源代码的质量,可以从七个维度检测代码质量通过插件形式,可以支持包括java,C#,C/C++,PL/S ...

  6. SpringBean基础装配

            首先,让我们先对Bean进行理解:什么是Bean,为什么要有Bean,如何装配Bean:         1,什么是Bean?             Bean你可以看成是一个组件,在 ...

  7. 【BZOJ4195】【NOI2015】程序自动分析(并查集)

    [BZOJ4195][NOI2015]程序自动分析(并查集) 题面 Description 在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足. 考虑一个约束满足问题的简化版本:假设 ...

  8. redis的常用公共方法

    实用redis已经有一段时间了,今天刚好有空记录一下所用到的方法,欢迎指正 首先我封装了一些字段信息 #region 字段 /// <summary> /// Redis服务器地址 /// ...

  9. 31.Django缓存和信号

    缓存 由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将某个views的返回值保存至内存或者memcache中, ...

  10. Unity3D判断角色对敌人是否可见

    在编写敌人AI的状态机时 经常需要判断角色对敌人来说是不是可见的 如果是可见的,则做出追击或者攻击动作 如果是不可见的,则保持idle或者巡逻状态 判断是否可见 包括两个步骤 1.地方角色的视见向量和 ...