二叉树遍历

二叉树的遍历

淺唱寂寞╮ 提交于 2020-02-09 07:50:28
二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的。对于二叉树,有前序、中序以及后序三种遍历方法。因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易理解而且代码很简洁。而对于树的遍历若采用非递归的方法,就要采用栈去模拟实现。在三种遍历中,前序和中序遍历的非递归算法都很容易实现,非递归后序遍历实现起来相对来说要难一点。 前序遍历 递归 void preOrder1(BinTree *root) //递归前序遍历 { if(root!=NULL) { cout<<root->data<<" "; preOrder1(root->lchild); preOrder1(root->rchild); } } 非递归 根据前序遍历访问的顺序,优先访问根结点,然后再分别访问左孩子和右孩子。即对于任一结点,其可看做是根结点,因此可以直接访问,访问完之后,若其左孩子不为空,按相同规则访问它的左子树;当访问其左子树时,再访问它的右子树。因此其处理过程如下: 对于任一结点P: 1)访问结点P,并将结点P入栈; 2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);若不为空,则将P的左孩子置为当前的结点P; 3)直到P为NULL并且栈为空,则遍历结束。 void preOrder2

二叉树三种遍历方式的非递归实现

南楼画角 提交于 2020-02-09 07:50:11
1、二叉树的先序遍历。 节点->左孩子->右孩子 用递归很容易解决,但是会遇到内存溢出情况。用栈可以解决找个问题。 根据前序遍历访问的顺序,优先访问根结点,然后再分别访问左孩子和右孩子。即对于任一结点,其可看做是根结点,因此可以直接访问,访问完之后,若其左孩子不为空,按相同规则访问它的左子树;当访问其左子树时,再访问它的右子树。因此其处理过程如下:   对于任一结点P: 1)访问结点P,并将结点P入栈; 2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);若不为空,则将P的左孩子置为当前的结点P; 3)直到P为NULL并且栈为空,则遍历结束。 1 public void xianxu(TreeNode root){ 2 Stack<TreeNode> stack = new Stack<>(); 3 TreeNode p = root; 4 while ( !stack.isEmpty() ){ 5 while ( p != null ){ 6 System.out.println(p.val); 7 stack.push(p); 8 p = p.left; 9 } 10 if ( !stack.isEmpty() ){ 11 p = stack.pop(); 12 p = p.right; 13 } 14 } 15

二叉树的遍历方式(迭代)

妖精的绣舞 提交于 2020-02-09 07:49:41
1.先序遍历 根据前序遍历访问的顺序,优先访问根结点,然后再分别访问左孩子和右孩子。即对于任一结点,其可看做是根结点,因此可以直接访问,访问完之后,若其左孩子不为空,按相同规则访问它的左子树;当访问其左子树时,再访问它的右子树。因此其处理过程如下:   对于任一结点P: 1)访问结点P,并将结点P入栈; 2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);若不为空,则将P的左孩子置为当前的结点P; 3)直到P为NULL并且栈为空,则遍历结束。 vector<int> PreOrder(TreeNode* root){ vector<int>res; if (!root)return res; stack<TreeNode*>ss; TreeNode* cur = root; while (cur || !ss.empty()){ if (cur){ res.push_back(cur->val); ss.push(cur); cur = cur->left; } else{ cur = ss.top(); cur = cur->right; ss.pop(); } } return res; } 2.中序遍历 根据中序遍历的顺序,对于任一结点,优先访问其左孩子,而左孩子结点又可以看做一根结点,然后继续访问其左孩子结点

教你如何迭代地遍历二叉树

牧云@^-^@ 提交于 2020-02-09 07:49:21
为何要迭代? 二叉树遍历是一个非常常见的操作,无论是中序遍历、先序遍历还是后续遍历,都可以用递归的方法很好地完成,但是相对来说迭代的方法难度就高不少,而且除此之外,迭代地遍历树至少有两个现实意义的优点: 1.比递归节省空间,递归是用栈实现的,因此如果树的高度h很大的话,递归很有可能会造成栈溢出 2.迭代的代码利用循环,而循环可以用循环不变量来证明代码的正确性 我们现在就分别详解这几个迭代地遍历树的方法。 先序遍历 我们先来看看先序遍历,因为在这个里面先序遍历用迭代实现是最简单的。我们先看递归的代码: class Solution: # @param root, a tree node # @return a list of integers def preorder(self,root): ans=[] self.dfs(root, ans) return ans def dfs(self,root,ans): if not root: return ans.append(root.val) self.dfs(root.left, ans) self.dfs(root.right,ans) 先序遍历就是先处理根节点,再处理左右子女节点,因此用迭代实现时,我们只要处理完根节点之后,把左右子女按照先右子女、后左子女的顺序推入栈来保证这个处理顺序就可以了。这个代码也很好理解: class

数据结构(三)——二叉树的相关操作

亡梦爱人 提交于 2020-02-09 03:29:59
前言 这里同样不介绍二叉树的相关概念,毕竟数据结构的基础已经讲过很多了,这里不再赘述。至于一些平衡二叉树,完全二叉树,红黑树,B+树等相关结构,这个已经有很多博客介绍了,这里只是介绍一下二叉树的一些基础操作。 定义 这个应该见过多次 /** * autor:liman * createtime:2020/2/6 * comment:二叉树节点的实现 */ public class TreeNode { public String value ; public TreeNode left ; public TreeNode right ; public TreeNode ( String value ) { this . value = value ; } } 遍历的非递归实现 递归的实现非常简单,估计很多人都会,这里就介绍非递归的遍历实现 基本的遍历操作如下:这里示意的输出一下表示遍历操作 /** * 做遍历的操作。 * * @param node */ public static void doTraverse ( TreeNode node ) { System . out . print ( node . value + " " ) ; } 先序遍历 /** * 非递归实现的先序遍历,这里用到了栈的操作 * * @param root */ public static

递归遍历二叉树

时间秒杀一切 提交于 2020-02-09 00:23:27
#二叉树结点 class BinaryTreeNode(object): def __init__(self): self.data='#' self.LeftChild=None self.RightChild=None #二叉树类,创建二叉树和遍历二叉树 class BinaryTree(object): def CreateBinaryTree(self,Root): data=input('->') if data=='#': Root=None else: Root.data=data Root.LeftChild=BinaryTreeNode() self.CreateBinaryTree(Root.LeftChild) Root.RightChild=BinaryTreeNode() self.CreateBinaryTree(Root.RightChild) def PreOrder(self,Root): if Root is not None: self.VisitBinaryTreeNode(Root) self.PreOrder(Root.LeftChild) self.PreOrder(Root.RightChild) def InOrder(self,Root): if Root is not None: self.InOrder(Root

非递归遍历二叉树

旧城冷巷雨未停 提交于 2020-02-08 23:06:54
#类名称:BinaryTreeNode #类说明:定义一个二叉树的结点 #类释义:分别有左孩子LeftChild,右孩子RightChild和数据data class BinaryTreeNode(object): def __init__(self): self.data='#' self.LeftChild=None self.RightChild=None class TreeState(object): def __init__(self,BinaryTreeNode,VisitedFlag): self.BinaryTreeNode = BinaryTreeNode self.VisitedFlag = VisitedFlag #类说明:定义一个二叉树 class BinaryTreeNonRecursive(BinaryTreeNode): #创建二叉树的函数 def CreateBinaryTree(self,Root): data=input('->') if data=='#': Root=None else: Root.data=data Root.LeftChild=BinaryTreeNode() self.CreateBinaryTree(Root.LeftChild) Root.RightChild=BinaryTreeNode() self

数据结构——二叉树的遍历(c/c++)

给你一囗甜甜゛ 提交于 2020-02-08 19:12:10
递归遍历: 二叉树的三种递归遍历为先序遍历,中序遍历和后续遍历。它们相似之处在于都是对二叉树的递归遍历且对任何一个结点都经过三次,区别在于哪一次对该结点进行访问,由此分为先,中,后序遍历。所以对于任一结点都有:三次经过,一次访问。 先序遍历: void preorder(btNode* p) { if (p != NULL) { visit(p); preorder(p->lc); preorder(p->rc); } } 中序遍历: void inorder(btNode* p) { if (p != NULL) { inorder(p->lc); visit(p); inorder(p->rc); } } 后序遍历: void postorder(btNode* p) { if (p != NULL) { postorder(p->lc); postorder(p->rc); visit(p); } } 对于下图中的树: 先序遍历结果为:ABDECF 根 左 右 中序遍历结果为:DBEAFC 左 根 右 后序遍历结果为:DEBFCA 左 右 根 中序与先(后)序可唯一确定一颗二叉树。 层序遍历: 二叉树的层序遍历的实现思路:建立一个辅助数据结构队列,将二叉树头节点入队,在出队时将其左右孩子挨个入队,每出队一个结点,将其左右孩子入队,直至队列为空。 void level

非线性数据结构——树

微笑、不失礼 提交于 2020-02-08 16:52:52
树 非线性数据结构定义:也就是每个元素可以有多个前驱和后继。树是一种非线性结构。它可以有两种定义。 第一种:树是n(n>=0, n为0时,称为空树 )个元素的集合,它只有 一个特殊的没有前驱的元素 ,这个元素成为树的 根(root) ,而且 树中除了根节点外,其余的元素都只能有一个前驱,可以有0个或者多个后继。 第二种递归定义:树T是n(n>=0,n为0时,称为空树)个元素的集合,它有且只有一个特殊元素根,剩余元素都可以被划分为M个互不相交的集合T1,T2,T3……、Tm,而每一个集合都是树,称为T的子树subtree,同时,子树也有自己的根。 维基百科是这样定义的: 树中的概念 结点: 树中的数据元素,也就是上图中的,A,B,C,D,E,F,G…… 结点的度degree :节点拥有的子树的数目称为度,记作d(v)。 叶子结结: 节点的度为0,称为叶子节点leaf,终端节点,末端节点。 分支结点: 节点的度不为0,称为非终端节点或分支节点。 分支: 节点之间的关系。 内部节点: 除根节点外的分支节点,当然也不包括叶子节点。 树的度: 树内各节点的度的最大值,比如下面这个图D节点的度最大为3,所以树的度数就是3. 孩子(儿子child)节点: 节点的子树的根节点成为该节点的孩子。 双亲(父parent)节点: 一个节点是他各子树的根节点的双亲。 兄弟(sibling)节点:

数据结构二叉树的查找与遍历

Deadly 提交于 2020-02-08 13:47:46
二叉树的查找与遍历 1、有n个结点的满二叉树,计算它的度为1的结点数目、叶子结点的数目。 设度为1的结点数目为n1,叶子结点数目为n0,度为2的结点数目为n2,因该二叉树为满二叉树,所以度数为1的结点数目为0,然后根据n0=n2+1;又因为n=n0+n2;所以n=2n0-1;所以叶子结点数目为n0=2n0/2; 2、已知完全二叉树的第7层上有10个叶子,则该二叉树至多有多少个结点? 该二叉树结点数达到最大值,深度为因为8,最少深度可以为7,前七层应为满二叉树, 第七层的叶子应为本层的最右边,第8层的结点数目为(27-1_ 10)*2=108,这颗二叉树的总结点为 (27-1_ 10)*2+ (27-_ 1)=235 3、已知某度为k的树中,其度为0、1、2、…、k-1的结点数分别为n0、n1、n2、…、nk-1。求该树的结点总数n,并给出推导过程。 设该树中的叶子数为n0个。该树中的总结点数为n个,则有: n=n0+n1+n2+…+nK (1) n-1=0*n0+1*n1+2*n2+…+K*nK (2) //去掉根结点 联立(2)-(1)方程组可得: 叶子数为:n0=1+0*n1+1*n2+2*n3+...+(K-1)*nK ∴树的结点总数n=k 来源: CSDN 作者: zhupengqq1 链接: https://blog.csdn.net/zhupengqq1/article