后序遍历

L2-006. 树的遍历

耗尽温柔 提交于 2020-03-13 12:46:54
L2-006. 树的遍历 给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。 输入格式: 输入第一行给出一个正整数N(<=30),是二叉树中结点的个数。第二行给出其后序遍历序列。第三行给出其中序遍历序列。数字间以空格分隔。 输出格式: 在一行中输出该树的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。 输入样例: 7 2 3 1 5 7 6 4 1 2 3 4 5 6 7 输出样例: 4 1 6 3 5 7 2 思路:我没有学过数据结构,也就是了解过堆和线段树,利用二叉树的遍历来还原二叉树也是蛮有意思的。 首先观察后序遍历,根据后序遍历的特点,可以发现最后一个节点一定是子树根节点,所以样例中的4便是祖先节点。然后再观察中序遍历,中序遍历的特点就是先把左子树的节点输出,在输出根节点,在输出右子树。根据前序遍历,就可以发现,根节点的左子树集合和右子树集合。 不管二叉树是如何遍历的,每子颗树上节点一定是在一个挨在一起的,只是访问的先后顺序不同。然后观察4的左子树,利用后序遍历可以找的左子树的根节点为1,在中序遍历中观察1,发现他只有一个右子树{2,3},利用后序遍历可知3是1的右子树,2是3的左子树。 同样的道理,对4的右子树的后序遍历进行见检查,发现6是右子树的根节点,利用中序遍历可知,6的左孩子为5,右孩子为7。

Python实现完全二叉树以及遍历

早过忘川 提交于 2020-03-11 17:57:09
在学校刚刚学到的二叉树是用C语言来实现的,还涉及到了指针等操作。最近疫情原因不能开学,就自己学习了一下Python,就拿Python来试着实现一下,顺便再复习一下二叉树的一些知识。 本文使用Python来构建一个完全二叉树,并且实现树结点添加,层次遍历,先序遍历,中序遍历,后序遍历。 由于我自己对二叉树的理解也不是很深,所以关于二叉树的理论知识就只能自行脑补了,这里直接开始实现了,在实现的过程中也可能会有一些错误,还请大佬们批评指正。 以下为实现的思路,完整代码以及输出可以直接滑倒最后查看。 创建结点 首先创建一个结点的类,结点含有数据和左子,右子,创建后就直接将左子,右子初始化为None,数据则从外部输入进去。 # 创建一个结点的class class Node(object): def __init__(self,valua): self.valua = valua self.Lchild = None self.Rchild = None 然后创建一个二叉树的类,因为结点已经创建了一个node的类,这里只需要初始化一个根结点为None就可以了。 # 创建一个二叉树class class Btree(object): def __init__(self): # 初始化根结点 self.root = None 添加结点 接下来就可以来实现添加结点的funtion类。

由树的中后序遍历求树的前层序遍历

眉间皱痕 提交于 2020-03-11 05:11:51
题目意思言简意赅 输入:输入第一行给出一个正整数 N( ≤ 3 0),是二叉树中结点的个数。第二行给出其后序遍历序列。第三行给出其中序遍历序列。数字间以空格分隔。 eg:input: 7 2 3 1 5 7 6 4 1 2 3 4 5 6 7output:4132657注意这个树非常丑陋:      4     / \    1   6     \ / \     3 5 7     /    2           首先是先序排列:根据后序的最后一个可以找到根的位置,然后再根据根在中序里面搜索,分为左右子树 详情可以参考这篇题解 https://www.luogu.org/blog/user21653/solution-p1030 这个输入输出有点区别,但原理是一样的 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int inf=1<<30; 4 typedef long long ll; 5 typedef pair<int,int> P; 6 const double pi=acos(-1); 7 const int mod=1e8+7; 8 const int maxn=140; 9 const int maxm=6300; 10 int a[maxn],b[maxn];//a存后序遍历,b存中序遍历

二叉树的基础遍历---前序遍历,中序遍历以及后序遍历

早过忘川 提交于 2020-03-10 05:08:35
二叉树的基础遍历 1:前序遍历 :先访问根结点,然后再访问左子树,最后访问右子树; 2:中序遍历 :先访问左子树,然后再访问根结点,最后访问右子树; 3:后序遍历 :先访问左子树,然后再访问右子树,最后访问根结点; 示例如下: 前序遍历的API设计: public Queue preErgodic():使用前序遍历,获取整个树中的所有键 private void preErgodic(Node x,Queue keys):使用前序遍历,把指定树x中的所有键放入到keys队列中 实现步骤: 把当前结点的key放入到队列中; 找到当前结点的左子树,如果不为空,递归遍历左子树; 找到当前结点的右子树,如果不为空,递归遍历右子树; 代码实现: //使用前序遍历获取整个树中所有的键 public Queue < Key > preErgoidic ( ) { Queue < Key > keys = new Queue < > ( ) ; preErgoidic ( root , keys ) ; return keys ; } //使用前序遍历获取指定树x的所有键,并放到Keys队列中 private void preErgoidic ( Node x , Queue < Key > keys ) { if ( x == null ) { return ; } /

二叉树遍历

冷暖自知 提交于 2020-03-09 18:17:40
两种遍历树的策略: 深度优先搜索(DFS) 在这个策略中,我们采用深度作为优先级,以便从跟开始一直到达某个确定的叶子,然后再返回根到达另一个分支。 方法一、递归 深度优先搜索策略又可以根据根节点、左孩子和右孩子的相对顺序被细分为前序遍历,中序遍历和后序遍历。 前序遍历:根->左->右 中序遍历:左->根->右 后序遍历:左->右->根 res.push_back(root->val);//打印根节点 helper(root->left); helper(root->right); 迭代 深度优秀遍历用递归求解非常简单,难的是 迭代 方法: 前序遍历 首先我们应该创建一个 Stack 用来存放节点,首先我们想要打印根节点的数据,此时Stack里面的内容为空,所以我们优先将头结点加入Stack,然后打印。 之后我们应该先打印左子树,然后右子树。所以先加入Stack的就是右子树,然后左子树。 此时你能得到的流程如下: vector<int> preorderTraversal(TreeNode* root) { vector<int> res; if(!root)return {}; stack<TreeNode*> s; TreeNode *tmp=root; while(tmp || !s.empty()){ if(tmp){ s.push(tmp); res.push_back

前中后序遍历

好久不见. 提交于 2020-03-09 15:25:16
今天看了一些关于平和查找二叉树的问题,顺便也复习了一下二叉树的遍历规则,写一下学习文档。 树的遍历顺序大体分为三种:前序遍历(先根遍历、先序遍历),中序遍历(中根遍历),后序遍历(后根遍历)。 前序遍历:前序遍历可以记为根左右,若二叉树为空,则结束返回。 前序遍历的规则: (1)访问根节点 (2)前序遍历左子树 (3)前序遍历右子树 这里需要注意:在完成第2,3步的时候,也是要按照前序遍历二叉树的规则完成。 中序遍历:中序遍历可以记为左根右,也就是说在二叉树的遍历过程中,首先要遍历二叉树的左子树,接着遍历根节点,最后遍历右子树。 同样,在二叉树为空的时候,结束返回。 中序遍历的规则: (1)中序遍历左子树 (2)访问根节点 (3)中序遍历右子树 注意:在完成第1,3步的时候,要按照中序遍历的规则来完成。 后序遍历:后序遍历可以记为左右根,也就是说在二叉树的遍历过程中,首先按照后序遍历的规则遍历左子树,接着按照后序遍历的规则遍历右子树,最后访问根节点。 在二叉树为空的时候,结束返回。 后序遍历二叉树的规则: (1)后序遍历左子树 (2)后序遍历右子树 (3)访问根节点 注意:在完成1,2步的时候,依然要按照后序遍历的规则来完成。 来源: https://www.cnblogs.com/ltc3344/p/12448565.html

给定前序和中序遍历,输出后序遍历。

我只是一个虾纸丫 提交于 2020-03-09 09:12:45
啊啊啊啊,今天有事没能去听老赵的讲座好遗憾。上一次是范玮琪张敬轩的演唱会,开在家门口的演唱会都没去。这次是ssp计划发起者的讲座,同样是开在家门口的,我都与之插肩而过。 从这一篇开始就是正式的“技术”博客了。姑且叫“技术”吧,词穷,我知道技术含量不高。。若有任何想法,欢迎大家一起交流讨论。 今天看了《 ACM-ICPC程序设计系列:图论及应用 》第二章关于树的部分。主要是关于一些树的定义和一些算法。 书上的例题只给了思路没有代码。我在网上找到了原题。 View Code /* 【题目来源】 http://acm.cs.ecnu.edu.cn/problem.php?problemid=1284 【题目分析】 给定树的前序遍历和中序遍历,要求输出后序遍历。 【思路分析】 1.前序遍历中:第一个元素就是根。 2.中序遍历中: 找到根的位置。 根的左边是根的左子树的中序遍历,右边是根的右子树的中序遍历。 得到左子树元素个数L。 3.前序遍历中: 除去根,前L个元素是左子树的前序遍历。剩下的是右子树的前序遍历。 4.这样就得到了左子树和右子树的前序遍历和中序遍历。对左子树和右子树递归下去,一定会出现树空的情况或只剩下一个元素的情况。 当树空的时候返回,当元素只有一个的时候,输出来并返回。 对左子树和右子树递归下去完成后就输出根节点。这样就得到了完整的后序遍历。 【附加细节】 substr

根据前序遍历和中序遍历求后序遍历

做~自己de王妃 提交于 2020-03-09 07:53:04
根据前序遍历和中序遍历求后序遍历 一道HULU的笔试题(How I wish yesterday once more) 假设有棵树,长下面这个样子,它的前序遍历,中序遍历,后续遍历都很容易知道。 PreOrder: GDAFEMHZ InOrder: ADEFGHMZ PostOrder: AEFDHZMG 现在,假设仅仅知道前序和中序遍历,如何求后序遍历呢?比如,已知一棵树的前序遍历是”GDAFEMHZ”,而中序遍历是”ADEFGHMZ”应该如何求后续遍历? 第一步,root最简单,前序遍历的第一节点G就是root。 第二步,继续观察前序遍历GDAFEMHZ,除了知道G是root,剩下的节点必然是root的左右子树之外,没法找到更多信息了。 第三步,那就观察中序遍历ADEFGHMZ。其中root节点G左侧的ADEF必然是root的左子树,G右侧的HMZ必然是root的右子树。 第四步,观察左子树ADEF,左子树的中的根节点必然是大树的root的leftchild。在前序遍历中,大树的root的leftchild位于root之后,所以左子树的根节点为D。 第五步,同样的道理,root的右子树节点HMZ中的根节点也可以通过前序遍历求得。在前序遍历中,一定是先把root和root的所有左子树节点遍历完之后才会遍历右子树,并且遍历的右子树的第一个节点就是右子树的根节点。

由中序遍历和后序遍历求前序遍历

佐手、 提交于 2020-03-09 07:30:37
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 typedef long long LL; 7 const int maxn = 30; 8 char in[maxn], post[maxn]; 9 void Build_PostTree(char *in, char *post, int len) 10 { 11 if(len == 0) return; 12 cout << *(post + len - 1); 13 int i = 0; 14 for( ; i < len; i++) 15 if(in[i] == *(post + len - 1)) break; 16 Build_PostTree(in, post, i); //Left 17 Build_PostTree(in + i + 1, post + i, len - i - 1); // Right 18 return ; 19 } 20 int main() 21 { 22 freopen("in.txt","r",stdin); 23 while(scanf("%s %s", in, post) != EOF){ 24 int len

【树的遍历】前序中序求后序,中序后序求前序

喜你入骨 提交于 2020-03-09 07:25:22
1>求前序 #include<cstdio> #include<cstdlib> #include<iostream> using namespace std; string m,f; int len,mid[30],front[30]; int son[30][2],root; int fz(int l1,int r1,int l2,int r2) { if(l1>r1) return 0; if(l1==r1) return front[l1]; int rt=front[l1]; int pos; for(pos=l2;pos<r2;pos++) if(mid[pos]==rt) break; int ln=pos-l2; son[rt][0]=fz(l1+1,l1+ln, l2,l2+ln-1); son[rt][1]=fz(l1+ln+1,r1, l2+ln+1,r2); return rt; } void back(int rt) { if(son[rt][0]) back(son[rt][0]); if(son[rt][1]) back(son[rt][1]); printf("%c",'A'+rt-1); } int main() { cin>>m>>f; len=m.length() ; for(int i=0;i<len;i++) mid[i]=m[i]-'A'