先序遍历

二叉树的非递归遍历

徘徊边缘 提交于 2019-11-28 05:50:53
二叉树的遍历我想大家都知道了,主要有先序、中序、后序,递归的遍历我就不说了,今天小编给大家主要介绍下二叉树的非递归遍历。 节点结构体: #include<stack> enum tag { L, R }; template<typename T>//可以变成类 struct BintNode { BintNode():left(nullptr),right(nullptr),value(0){} BintNode(T v) { left = nullptr; right = nullptr; value = v; } T value; BintNode<T> *left; BintNode<T> *right; }; template<typename E> struct stkNode { stkNode(BintNode<E>*N=nullptr):ptr(N), r(L){} BintNode<E>*ptr; tag r; }; 首先是先序遍历,借助栈实现的。 void nonrepreorder(BintNode<Y>*root)const//非递归先序 { if (root) { stack<BintNode<Y>*> bitr; bitr.push(root); BintNode<Y>*p; while (!bitr.empty()) { p = bitr.top();

二叉树的遍历

被刻印的时光 ゝ 提交于 2019-11-28 01:35:34
import java.util.ArrayList;import java.util.Iterator;import java.util.LinkedList;import java.util.Stack;/** * Created by zhouguojing on 2019/8/20. */public class TreeNode { int val; TreeNode left; TreeNode right; public TreeNode(int val) { this.val = val; }//先序遍历 public static ArrayList<Integer> preOrder(TreeNode root) { ArrayList<Integer> list = new ArrayList<Integer>(); if(root == null) return null; list.add(root.val); if(root.left!=null) list.addAll(preOrder(root.left)); if(root.right!=null) list.addAll(preOrder(root.right)); return list; } //中序遍历 public static ArrayList<Integer> inOrder

20182311 2019-2020-1 《数据结构与面向对象程序设计》第9周学习总结

那年仲夏 提交于 2019-11-27 16:58:10
目录 教材学习内容总结 教材第15章 教材第16章 教材学习中的问题和解决过程 代码调试中的问题和解决过程 代码托管 上周错题总结 点评过的同学博客和代码 学习进度条 正文 20182311 2019-2020-1 《数据结构与面向对象程序设计》第9周学习总结 教材学习内容总结 教材第15章 树的概述 定义:树是一种非线性结果,元素按分层组织。它含有结点和连接结点的边,位于树最高层的是根节点root,结点相对于根节点的位置表示结点的层。树中不含有子节点的结点为叶结点,除叶结点和根结点外的其他结点都是内节点。 树的阶:结点含有的最大子结点数。 路径长度:连接两个结点边的数量。高度:从根结点到叶结点的最长路径的长度。 n元树:任一结点的子节点数目不多于n的 平衡:所有叶结点都位于同一层 完全:树平衡,且最底层的叶结点都在树的左边 树的实现: 数组实现策略:使用数组实现树,数组下标为n的结点的左子树下标为2n,右子树下标为2n+1。思路简单,访问迅速,但是该数组会为不含数据的树位置分配空间,浪费存储空间。 模拟连接策略:在数组中存入孩子的数组索引,为了节省空间会增加删除树中元素时,数组元素进行移位的成本。 链表实现:链表是最常见的造树方法,二叉链表可连接左右节点,三叉链表可指向父节点,多叉链表可以指向更上一级或者siblings 树的遍历:递归遍历比非递归遍历更简单

二叉树先序、中序、后序、层次遍历递归以及非递归算法实现

ぐ巨炮叔叔 提交于 2019-11-27 15:59:52
最近写了一下关于二叉树的三种遍历算法的递归以及非递归实现,以及层次遍历算法实现 先序遍历递归实现 /** * 先序遍历,根》左》右 */ public void beforeTraverse ( TreeNode root ) { if ( root == null ) { return ; } System . out . print ( root . val + "->" ) ; if ( root . left != null ) { beforeTraverse ( root . left ) ; } if ( root . right != null ) { beforeTraverse ( root . right ) ; } } 先序遍历非递归实现 /** * 通过栈遍历二叉树,先序(思想就是:入栈即记录) */ public List < String > beforeTraverseByStack ( TreeNode root ) { List < String > list = new ArrayList < > ( ) ; // 接受结果 if ( root == null ) { return list ; } Stack < TreeNode > stack = new Stack < > ( ) ; // 先序遍历(根 》左 》右),先遍历所有左结点

二叉树的遍历

妖精的绣舞 提交于 2019-11-27 07:46:46
二叉树的遍历是指通过一定的顺序访问二叉树的所有结点。遍历方法一般有四种:先序遍历、中序遍历、后序遍历和层次遍历,其中,前三种一般使用深度优先搜索(DFS)实现,而层次遍历一般使用广度优先搜索(BFS)实现 把一颗二叉树分为三个部分:根节点、左子树、右子树,且对左子树和右子树可以同样进行这样的划分,这样对树的遍历就可以分为对这三个部分的遍历,这三种方法中,左子树一定要先于右子树遍历,且所谓的“先中后”都是指根节点root在遍历中的位置,因此先序遍历的访问顺序是根节点-左子树-右子树;中序遍历的访问顺序是左子树-根节点-右子树;后序遍历的访问顺序是左子树-右子树-根节点。 先序遍历 1、先序遍历的实现 对先序遍历来说,总是先访问根节点root,再访问左子树和右子树,因此先序遍历的顺序是根节点-左子树-右子树 为了实现递归的先序遍历,需要得到两样东西:递归式和递归边界。其中递归式已经可以由先序遍历直接得到,即先访问根节点(可以做任何事情),再递归访问左子树,最后递归访问右子树,递归边界就是子树为空 先序遍历的代码如下: void preorder(node *root){ if(root==NULL){ //到达空树,递归边界 return; } //访问根节点root,例如将其数据域输出 printf("%d\n",root->data); //访问左子树 preorder(root-

先序+中序遍历重建二叉树

梦想与她 提交于 2019-11-27 07:46:43
假设已知先序序列为pre1,pre2,pre3……pren,中序序列为in1,in2,in3,……,inn,如图所示,那么由先序序列的性质可知,先序序列的第一个元素pre1是当前二叉树的根节点,再由中序序列的性质可知,当前二叉树的根节点将中序序列划分为左子树和右子树。因此,要做的就是在中序序列中找到某个结点ink,使的ink==pre1,这样就在中序序列中找到了根节点。易知左子树的结点个数是numleft=k-1.于是,左子树的先序序列区间就是[2,k],左子树的中序序列区间就是[1,k-1];右子树的先序序列区间就是[2,k],右子树的中序序列区间是[k+1,n],接着只需要在左子树和右子树上进行递归重建二叉树即可。 事实上,如果递归过程中当前序列的区间为[prel,prer],中序序列的区间为[inl.inr],那么左子树的结点个数为numleft=k-inl.这样左子树的先序序列区间为[prel+1,prel+numleft],左子树的中序序列区间为[inl,k-1];右子树的先序序列区间为[prel+numleft+1,prer],右子树的中序序列区间为[k+1,inr]; 那么,如果一直这样递归下去,什么时候结束呢?问题的答案是显然的,因为只要先序序列的长度小于等于0时,当前二叉树就不存在了,以此作为递归的边界。 代码如下: //当前先序序列的区间为[prel,prer]

二叉树 ADT接口 遍历算法 常规运算

徘徊边缘 提交于 2019-11-27 03:32:47
BTree.h (结构定义, 基本操作, 遍历) #define MS 10 typedef struct BTreeNode{ char data; struct BTreeNode * left struct BTreeNode * right; }BTreeNode; BTreeNode* InitBTree(); /*初始化二叉树,即把树根指针置空*/ BTreeNode* CreateBtree(char *a); /*根据a所指向的二叉树广义表字符串建立对应的存储结构,返回树根指针*/ int BTreeEmpty(BTreeNode* BT); /*判断一颗二叉树是否为空,若是则返回1,否则返回0*/ void Preorder(BTreeNode * BT); /*先序遍历的递归算法*/ void Inorder(BTreeNode * BT); /*中序遍历的地鬼算法*/ void Postorder(BTreeNode * BT); /*后序遍历的递归算法*/ void Levelorder(BTreeNode* BT); /*按层遍历由BT指针所指向的二叉树*/ void Inorder(BTreeNode* BT); /*对二叉树进行中序遍历的非递归算法*/ int BTreeDepth(BTreeNode * BT); /*求BT指向的一颗二叉树深度*/

图的遍历

雨燕双飞 提交于 2019-11-27 00:24:02
没有用的话qaq : Ummmm…图论的大部分知识本来早就有学过,只是一直没有写成博文来梳理,但既然上了qbxt DP图论就写一篇来总结下, 主要是来听DP的,但…由于太菜的原因,DP听得天花乱坠QWQ 图的遍历分为两种,图的深度优先遍历和图的广度优先遍历,深度优先遍历是用栈来实现的,可以用手写栈,也可以递归(要小心没开栈的时候爆栈) 一,图的深度优先遍历 实现很简单,和dfs一样,分为以下几个步骤 1,从起点s开始遍历 2,当遍历到节点u时,如果u节点没有被访问过,那么就访问u在访问u没有被访问过的相邻节点,一直到头.... 3,当所有节点都被访问之后,遍历结束。 inline void dfs(int s) { vis[s]=true; for(int i=first[s];i;i=edge[i].nxt) { if(!vis[edge[i].ed]) dfs(edge[i].ed); } } 二叉树的三种dfs序:先序遍历,中序遍历,后序遍历 1,前序遍历:先访问根节点,然后依次访问每一棵子树,如上述过程一样。 比如上图的先序遍历为B,F,E,K,L 2,中序遍历:先访问左子树,再访问根节点,再访问右子树。 比如上图的中序遍历为F,B,K,E,L 3,后序遍历:先访问左子树,再访问右子树,最后访问根节点 比如上图的后序遍历为F,K,L,E,B * 二,图的广度优先遍历

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

断了今生、忘了曾经 提交于 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