二叉树遍历

【转】二叉树的非递归遍历

和自甴很熟 提交于 2019-11-27 01:23:49
原文: http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html 二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的。对于二叉树,有前序、中序以及后序三种遍历方法。因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易理解而且代码很简洁。而对于树的遍历若采用非递归的方法,就要采用栈去模拟实现。在三种遍历中,前序和中序遍历的非递归算法都很容易实现,非递归后序遍历实现起来相对来说要难一点。 一.前序遍历 前序遍历按照“根结点-左孩子-右孩子”的顺序进行访问。 1.递归实现 void preOrder1(BinTree * root) // 递归前序遍历 { if (root != NULL) { cout << root -> data << " " ; preOrder1(root -> lchild); preOrder1(root -> rchild); } } 2.非递归实现 根据前序遍历访问的顺序,优先访问根结点,然后再分别访问左孩子和右孩子。即对于任一结点,其可看做是根结点,因此可以直接访问,访问完之后,若其左孩子不为空,按相同规则访问它的左子树;当访问其左子树时,再访问它的右子树。因此其处理过程如下: 对于任一结点P: 1)访问结点P,并将结点P入栈

二叉树非递归遍历

淺唱寂寞╮ 提交于 2019-11-27 01:23:05
1、二叉树递归遍历很简单,以前序遍历为例说明: 1 void PrefixOrder(Node* node) 2 { 3 if (node!= NULL) 4 { 5 cout<<root->value<< " " ; 6 PrefixOrder(root-> lchild); 7 PrefixOrder(root-> rchild); 8 } 9 }   中序遍历和后序遍历类似。 2、考虑二叉树非递归遍历,思路:前序遍历特点,访问当前节点,然后访问左孩子,左孩子有孩子,继续访问左孩子的左孩子节点,直到没有左孩子,访问右孩子。因此。非递归遍历的思路就是,使用while,记录当前节点,往左一条路走到底,然后原路后退,访问右节点。 转载于:https://www.cnblogs.com/nzbbody/p/3450144.html 来源: https://blog.csdn.net/weixin_30231093/article/details/99234535

遍历结果推导二叉树

。_饼干妹妹 提交于 2019-11-27 01:22:59
1、根据前序与中序,推导二叉树。举例来说:前序ABC,中序CAB,由前序直到A为根节点,由中序知道A的左边为左孩子,右边为右孩子。C为左孩子,B为右孩子。 2、思考,由前序和后续,能否退出二叉树?   前序ABC,后序CBA。由前序ABC知道A为根节点,后面分成两块,每一块都是前序,前面一块为左孩子,后面一块为右孩子。由后序知道A为根节点,前面分成两块,每一块都是后序,前面一块为左孩子,后面一块为右孩子。都是分成两块,对于分成的两块,前面一块元素集合相同,后面一块元素集合相同。注意,集合不考虑元素的顺序。这样,就有两种情况:   a、前面一块为BC,后面一块为空   b、前面一块为空,后面一块为BC   因此,根据前序与后序不能推导出二叉树。 3、思考,前序与后序一定不能推导出二叉树吗?   考虑,前序ABC,后续BCA,同样道理,分成两块的情况:   a、前面一块为B,后面一块为C   b、前面一块为BC,后面一块为空   c、前面一块为空,后面一块为BC   分成两块,每一块都是前序或者后序,但是,前序与后序的顺序一定不一样,对于b,c两种情况,前序与后序顺序一样,因此排除,只剩下a情况。推导出唯一的二叉树。 因此,根据前序与后序不能推导出二叉树,但是某些特殊情况下,可以推导出二叉树。 转载于:https://www.cnblogs.com/nzbbody/p/3450168

c++ 二叉树遍历

时光总嘲笑我的痴心妄想 提交于 2019-11-26 23:16:07
题目描述 二叉树是每个内部结点最多只有两个子结点且两个子结点有序的树。如下图就是一棵二叉树: 对于一棵二叉树,有三种基本遍历方式: 1.前序遍历:先访问根结点,然后再前序遍历左子树,最后前序遍历右子树; 2.中序遍历:先中序遍历左子树,然后访问根结点,最后中序遍历右子树; 3.后序遍历:先后序遍历左子树,然后后序遍历右子树,最后访问根结点。 对于上图,前序遍历的结果是ABDEHCFGI。中序遍历的结果是DBEHAFCIG,后序遍历的结果是DHEBFIGCA。 现在给出二叉树的前序和中序遍历,请输出相应的后序遍历。 输入 第一行前序遍历的结果 第二行中序遍历的结果 都是大写字母,且结点的标识不重复,最多只有100个结点。 输出 输出后序遍历的结果 样例输入 ABDEHCFGI DBEHAFCIG 样例输出 DHEBFIGCA Source Code #include <iostream> #include <string.h> using namespace std; char a[110],b[110];//a[]是前序遍历的结果 b[]是中序遍历的结果 void dfs(int f1,int e1,int f2,int e2) { if(f1>e1) return;//如果找不到子节点就退出(起点大于终点) int rt=f1;//rt是根节点 int p = 0; /

二叉树的前中后和层序遍历详细图解(递归和非递归写法)

断了今生、忘了曾经 提交于 2019-11-26 17:54:53
我家门前有两棵树,一棵是二叉树,另一棵也是二叉树。 遍历一棵二叉树常用的有四种方法,前序(PreOrder)、中序(InOrder)、后序(PastOrder)还有层序(LevelOrder)。 前中后序三种遍历方式都是以根节点相对于它的左右孩子的访问顺序定义的。例如根->左->右便是前序遍历,左->根->右便是中序遍历,左->右->根便是后序遍历。 而层序遍历是一层一层来遍历的。 树的前中后序遍历是个递归的定义,在遍历到根节点的左/右子树时,也要遵循前/中/后序遍历的顺序,例如下面这棵树: 前序遍历:ABDECFG 中序遍历:DBEAFCG 后序遍历:DEBFGCA 层序遍历:ABCDEFG 树的结点结构体声明如下: 语言:C语言(为了省事用到了C++的栈,因为C语言要用栈的话要自己重新写一个出来,就偷了个懒) 编译器:VS typedef char DataType; typedef struct TreeNode{ DataType data; struct TreeNode *left; struct TreeNode *right; }TreeNode; 1 2 3 4 5 6 7 前序遍历(先序遍历) 对于一棵树的前序遍历,递归的写法是最简单的(写起来),就是将一个大的问题转化为几个小的子问题,直到子问题可以很容易求解,最后将子问题的解组合起来就是大问题的解。

二叉树的遍历(前、中、后序及层次遍历,递归和非递归实现)

自古美人都是妖i 提交于 2019-11-26 17:05:00
一棵二叉树: 树的先序遍历序列preorder: DBACEGF( 根左右) 树的中序遍历序列inorder: ABCDEFG(左根右) 树的后序遍历序列postorder: ACBFGED(左右根) 树的层序遍历序列levelorder:DBEACGF(按行遍历) 输入一棵二叉树的先序遍历和中序遍历序列,输出它的后序遍历序列。 输入:DBACEGF ABCDEFG 输出:ACBFGED 思路: 已知先序遍历序列的第一个一定是本树的根节点,而后在中序遍历中找到该根节点的位置,中序遍历序列中根节点左边为左子树,右边为右子树,然后开始先左子树后右子树进行递归,因为要求的后序遍历序列是左右根,故在递归完左右子树后再输出根。 Code: 1 #include<bits/stdc++.h> 2 #define IO ios::sync_with_stdio(false) 3 using namespace std; 4 string preorder,inorder,aa;//分别为先序、中序、后序 5 int n,t; 6 void recover(int l,int r) 7 { 8 if(l>=r)return; 9 int root=preorder[t++];//先序遍历的第一个点一定是根节点 10 int m=distance(inorder.begin(),find

二叉树的遍历

我只是一个虾纸丫 提交于 2019-11-26 14:04:45
前序遍历 若树为空,则空操作返回。否则,先访问根节点,然后前序遍历左子树,再前序遍历右子树。(中 左 右) 中序遍历 若树为空,则空操作返回。否则,从根节点开始(注意并不是先访问根节点),中序遍历根节点的左子树,然后是访问根节点,最后中序遍历根节点的右子树。(左 中 右) 后续遍历 若树为空,则空操作返回。否则,从左到右先叶子后节点的方式遍历访问左右子树,最后访问根节点。(左 右 中) 层序遍历 若树为空,则空操作返回。否则,从树的第一层,也就是根节点开始访问,从上到下逐层遍历,在同一层中,按从左到右的顺序结点逐个访问。 /** * 前序遍历BST树的API接口 */ public void preOrder(){ System.out.print(“递归前序遍历:”); preOrder(this.root); System.out.println(); } /** * 前序遍历BST树的递归操作 VLR * @param root */ private void preOrder(BSTNode<T> root) { if(root != null){ System.out.print(root.getData() + " "); preOrder(root.getLeft()); preOrder(root.getRight()); } } /** *

数据结构(树与二叉树)

做~自己de王妃 提交于 2019-11-26 12:29:34
一、定义 树是n(n≥0)个结点的有限集合,n=0时,称为空树。(它是一种一对多的逻辑结构) 而对任意非空树应该满足: 1)有且仅有一个特定的称为根的结点。 2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集合,其中每一个集合本身又是一棵树,称为根结点的子树。 (其中A为根节点。BEF为根节点A的其中一个子树。) 观察可知树有以下两个特点: 1。树的根节点没有前驱结点,除根节点外的所有结点有且只有一个前驱结点。 2。树中所有结点可以有零个或多个后继结点 (重要结论:n个结点的树中只有n-1条边。) 二、基本术语 1)祖先结点和子孙结点 、双亲结点和孩子结点、兄弟结点 由根节点出发为了找到K,所经过的路径为: ABEK因此E、B、A均为K的祖先结点,而K为A、B、E的子孙结点 。看这样一个子树EKL,在这个子树中 K、L为E的孩子结点,而E为K、L的双亲结点,且K与L互为兄弟结点。 2)度 树中一个结点的子节点的个数称为该结点的度(如A、D的度为3,B、E的度为2,C的度为1,而F、G、H、I、J、K、L的度为0),而树中的最大度数称为树的度(容易看出该树的度为3) 3)分支结点与叶子结点 度大于0的结点称为分支结点,而度为0的结点称为叶子结点。(如A、B、C、D、E均为分支结点而F、G、H、I、J、K、L均为叶子结点。) 4)结点的层次、高度、深度 结点的层次

数据结构(十四)——二叉树

久未见 提交于 2019-11-25 20:25:28
数据结构(十四)——二叉树 一、二叉树简介 1、二叉树简介 二叉树是由n(n>=0)个结点组成的有序集合,集合或者为空,或者是由一个根节点加上两棵分别称为左子树和右子树的、互不相交的二叉树组成。 二叉树的五种形态: 2、二叉树的存储结构模型 树的另一种表示法:孩子兄弟表示法 A、每个结点都有一个指向其第一个孩子的指针 B、每个结点都有一个指向其第一个右兄弟的指针 孩子兄弟表示法的特性: A、能够表示任意的树形结构 B、每个结点包含一个数据成员和两个指针成员 C、孩子结点指针和兄弟结点指针构成树杈 3、满二叉树 如果二叉树中所有分支结点的度数都为2,并且叶子结点都在统一层次上,则二叉树为满二叉树。 4、完全二叉树 如果一棵具有n个结点的高度为k的二叉树,树的每个结点都与高度为k的满二叉树中编号为1——n的结点一一对应,则二叉树为完全二叉树。 完全二叉树的特性: A、同样结点数的二叉树,完全二叉树的高度最小 B、完全二叉树的叶子结点仅出现在最下边两层,并且最底层的叶子结点一定出现在左边,倒数第二层的叶子结点一定出现在右边。 C、完全二叉树中度为1的结点只有左孩子。 5、二叉树的特性 A、在二叉树的第i层上最多有2^(i-1)个结点(i>=1)。 B、高度为k的二叉树,最多有2^k-1个结点(k>=0)。 C、对任何一棵二叉树,如果其叶结点有n个,度为2的非叶子结点有m个,则 n = m