二叉树遍历

二叉树的遍历

若如初见. 提交于 2019-11-30 13:42:57
·1.Binary Tree Preorder Traversal 使用栈,时间复杂度O(n),空间复杂度O(n) public static void preOrderRec(Node root){ if (root != null) s.push(root); while (!s.isEmpty()) { final TreeNode p = s.pop(); result.add(p.val); if (p.right != null) s.push(p.right); if (p.left != null) s.push(p.left); } 递归先序遍历,时间复杂度O(n),空间复杂度O(n) public static void preOrderRec(Node root){   if(root!=null){   System.out.println(root.value);   preOrderRec(root.left);   preOrderRec(root.right); } } Morris先序遍历,时间复杂度O(n),空间复杂度O(1) 步骤: 1.如果当前节点的左孩子为空,则输出当前节点并将其右孩子作为当前节点。 2.如果当前节点的左孩子不为空,在当前节点的左子树中找到当前节点在中序遍历下的前驱节点。 a) 如果前驱节点的右孩子为空

二叉树搜索树中序遍历下的前驱节点与后继节点

守給你的承諾、 提交于 2019-11-30 13:34:31
前驱节点 前驱节点的值小于该节点的值,是该节点左子树中值最大的 后继节点 后继节点的值大于该节点的值,是该节点右子树中值最小的 因为二叉搜索树的中序遍历出来的结果就是一棵树节点上的值的升序排序,所以一个数的前驱节点的值就是比它小一个的数,后继节点的值就是比它大一个的节点 找前驱节点有以下情况: (1) 该节点有左子树,那么该节点的前驱节点就是其左子树中最大的那个。例如 10 它有左孩子,它的前驱节点就是左孩子中最大的也就是 8 。 (2) 该节点没有左子树,那么就又有两种情况: 1. 该节点是其父节点的右孩子,那么它的前驱就是他的父节点; 例如 17 它的前驱就是16 2. 该节点是其父节点的左孩子,那么就得往其祖辈寻找直到找到它祖辈是左孩子为止,如果没找到,那么说明该节点没有前驱节点。 例如 8 它是左孩子,所以它的前驱不是它的父亲,就得往上找, 而它的父亲是他爷爷的右孩子,所以 8 的前驱就应该是它的爷爷 7 。 找后继节点有以下情况: (1) 该节点有右子树,那么该节点的后继节点就是其右子树中最小的那个。例如 10 它有右子树 它的后继就是右子树中最小的那个 14 。 (2) 该节点没有右子树,那么它的后继节点也要往祖辈里面找,也是分两种情况 : 1. 该节点是其父节点的左子树,那么它的后继节点就是他的父亲; 2. 该节点是父节点的左子树, 那么往上找

二叉树先序、中序、后续遍历非递归

心不动则不痛 提交于 2019-11-30 13:20:01
1 ** 2 * 二叉树先序遍历非递归 3 * @param root 4 */ 5 public void preOrder_no_recursive(TreeNode root){ 6 if(root == null) return; 7 8 Stack<TreeNode> stack = new Stack<>(); 9 stack.add(root); 10 while(!stack.isEmpty()){ 11 TreeNode tn = stack.pop(); 12 System.out.println(tn.val); // 输出 13 if(tn.right != null) stack.add(tn.right); 14 if(tn.left != null)stack.add(tn.left); 15 } 16 } 17 18 /** 19 * 二叉树中序遍历非递归 20 * @param root 21 */ 22 public void inOrder_no_recursive(TreeNode root){ 23 if(root==null)return; 24 Stack<TreeNode> stk = new Stack<TreeNode>(); 25 TreeNode p = root;//辅助节点 26 stk.add(p); 27 while

二叉树的遍历算法

大城市里の小女人 提交于 2019-11-30 12:05:43
遍历(Traverse) 就是按照某种次序访问树中的所有结点,且每个结点恰好访问一次 也就是说,按照被访问的次序,可以得到由树中所有结点排成的一个序列 树的遍历也可以看成是人为的将非线性结构线性化 这里的“访问”是广义的,可以是对结点作各种处理,例如输出结点信息、更新结点信息等 在我们的现实中,并不真正的“访问”这些结点,而是得到一个结点的线性序列,以线性表的形式输出 将整个二叉树看做三部分:根、左子树、右子树。如果规定先遍历左子树、在遍历右子树,那么根据根的遍历顺序就有三种遍历方式: 左子树 右子树 根 先序/根遍历DLR:根 左子树 右子树 中序/根遍历LDR:左子树 根 右子树 后序/根遍历LRD:左子树 右子树 根 注意:由于树的递归定义,其实对三种遍历的概念其实也是一个递归的描述过程 先序/根遍历DLR:1 4 5 2 3 6 7 中序/根遍历LDR:4 5 1 3 2 6 7 后序/根遍历LRD:5 4 3 7 6 2 1 如果按层次遍历,没有递归 面试题:已知一棵二叉树的后序遍历的序列为5 4 3 7 6 2 1,中序遍历的序列为4 5 1 3 2 6 7,则其先序遍历的序列是什么? 只要给定中序遍历,先序遍历或者后序遍历再给一个,就可以求出另一个 后序遍历最后肯定是根,所以确定1是根 所以4 5是左子树,3 2 6 7是右子树 依此类推 /** *二叉链表的结点 *

学习笔记之二叉树的遍历

空扰寡人 提交于 2019-11-30 05:47:19
分层遍历 将每一层的节点遍历出来,利用 LinkedList ,先压入根节点,循环遍历,循环的同时再将左节点,右节点分别加到尾部. // 分层遍历 (TreeNode root) if ( root == null ) return ; LinkedList < TreeNode > nodes = new LinkedList < > ( ) ; TreeNode last = root ; TreeNode nLast = root ; nodes . push ( root ) ; while ( ! nodeStack . isEmpty ( ) ) { TreeNode node = nodes . pop ( ) ; System . out . print ( node . data + " " ) ; if ( node . left != null ) { nodes . add ( node . left ) ; nLast = node . left ; } if ( node . right != null ) { nodes . add ( node . right ) ; nLast = node . right ; } if ( node == last ) { System . out . println ( " " ) ; last = nLast

javascript实现二叉搜索树

≡放荡痞女 提交于 2019-11-30 01:38:36
在使用javascript实现基本的数据结构中,练习了好几周,对基本的数据结构如 栈、队列、链表、集合、哈希表、树、图等内容进行了总结并且写了笔记和代码。 在 github中可以看到 点击查看 ,可以关注一下我哈。 树的基本术语 二叉树节点的存储结构 创建一个二叉搜索树 二叉树的先序、中序、后续遍历算法 二叉树的非递归先序、中序、后续遍历算法 。 文章对树了解的不多的人有点不友好,这里简单介绍(从书上抄下来)那些基本的一点概念吧。 看下面这个示意图 树的基本术语: 结点: A、B、C等都是结点,结点不仅包含数据元素,而且包含指向子树的分支。例如,A结点不仅包含数据元素A、还包含3个指向子树的指针。 结点的度: 结点拥有的子树个数或者分支的个数,例如A结点有3棵子树,所以A结点的度为3. 树的度: 树中各结点度的最大值。如例子中结点度最大为3(A、D结点)。最小为0(F、G、I、J、K、L、M),所以树的度为3。 叶子节点 :又叫做 终端节点, 指度为0的节点,F、G、I、J、K、L、M节点都是叶子节点。 孩子: 结点的子树的根,如A节点的孩子为B、C、D。 双亲: 与孩子的定义对应,如B C D结点的双亲都是A。 兄弟: 同一个双亲的孩子之间互为兄弟。如B、C、D互为兄弟,因为它们都是A节点的孩子。 祖先 :从根到某节点的路径上的所有结点,都是这个节点的祖先。如K的祖先是A B E

二叉树遍历实现及效率分析

主宰稳场 提交于 2019-11-30 01:07:33
1 理论 1、二叉树遍历方法 先序遍历遍历顺序:根–左--右 中序遍历遍历顺序:左–根--右 后序遍历遍历顺序:左–右--根 层序遍历遍历顺序:从上到下,从左到右 2、二叉树复原 已知 先序遍历序列 和 中序遍历序列 ,可以唯一确定一颗二叉树 已知 中序遍历序列 和 后序遍历序列 ,可以唯一确定一颗二叉树 已知 先序遍历序列 和 后序遍历序列 , 不 能唯一确定一颗二叉树 3、二叉树存储 顺序存储:用一维数组存储二叉树中的节点,并且节点的存储位置,也就是数组的下标要能体现节点之间的逻辑关系,一般只用于完全二叉树 。 链式存储:每个节点的结构具有一个存储数据的变量与两个指向孩子的指针域。 2 代码 #include <iostream> #include <vector> #include <stack> #include <queue> #include <ctime> using namespace std; struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; #pragma region 先序遍历 void preorderRecursion(TreeNode* node) { if (node) {

已知二叉树先序遍历中序遍历求其后序遍历、重建二叉树

妖精的绣舞 提交于 2019-11-29 19:31:06
已知二叉树先序遍历中序遍历求其后序遍历 (注:已知中序遍历序列和剩下两种遍历序列中的一种都可以确定二叉树,即可得到另一种遍历序列, 但是已知前序遍历和后序遍历序列并不能唯一确定二叉树,例如:preorder:AB postorder:BA,我们不能确定B是A的左子还是右子。) 二叉树的先序遍历的第一个元素总是树的根结点,而在中序遍历中,根结点在序列的中间,其左右两边分别是根结点的左右子树。 因此我们可以根据先序遍历确定根结点,然后在中序遍历中扫描根结点,同时可得到左右子树的中序遍历和先序遍历,递归此过程,即可获得二叉树的所有结点。 而后序遍历即为根结点左子树的后序遍历+右子树的后序遍历+根结点。 递归实现思路非常简单,C++代码: string getpostorder(char* preorder, char* inorder, int length){ string str = ""; char* rootInorder; //根结点在中序遍历中的位置 int leftlength; //左子树长度 if (length <= 0||preorder==NULL||inorder==NULL)//递归边界条件 return ""; else{ leftlength = 0; rootInorder = inorder; //扫描根结点 while (leftlength <

二叉树的遍历

戏子无情 提交于 2019-11-29 18:36:30
一般的数据结构都有遍历操作,根据需求的不同,二叉树一般有四种遍历方式: 1、先序遍历 如果二叉树为空,遍历结束,否则,第一步,访问根节点;第二步,先序遍历根节点的左子树,第三部,先序遍历根节点的右子树。 2、中序遍历 如果二叉树为空,遍历结束,否则,第一步,中序遍历根节点的左子树;第二步,访问根节点,第三部,中序遍历根节点的右子树。 3、后序遍历 如果二叉树为空,遍历结束,否则,第一步,后序遍历根节点的左子树;第二步,后序遍历根节点的右子树,第三部,访问根节点。 4、层次遍历 从二叉树的第一层(根结点)开始,从上至下逐层遍历,在同一层,则按从左到右的顺序对结点逐个访问。 通过上面的理论可以总结出先序遍历和中序遍历来求解二叉树的过程,步骤如下: a)确定树的根节点。树根是当前树中所有元素在先序遍历中最先出现的元素,即先序遍历的第一个结点就是二叉树的根。 b)求解树的子树。找到根在中序遍历的位置,位置左边是二叉树的左孩子,位置右边是二叉树的右子树,如果根节点左边或右边为空,那么该方向子树为空;如果根节点左边和右边都为空,那么根节点已经为叶子节点。 c)对二叉树的左、右孩子分别进行步骤a)、b),直到求出二叉树结构为止。 来源: https://www.cnblogs.com/yazhong-java/p/11526318.html

二叉树

大兔子大兔子 提交于 2019-11-29 17:33:30
1.1 二叉树的定义:   二叉树 是一种特殊的树,它具有以下 特点 :   (1)树中每个节点最多只能有两棵树,即每个节点的度最多为2。   (2)二叉树的子树有左右之分,即 左子树 与 右子树 ,次序不能颠倒。   (3)二叉树即使只有一个子树时,也要区分是左子树还是右子树。    1.2 满二叉树:   满二叉树 作为一种特殊的二叉树,它是指:所有的分支节点都存在左子树与右子树,并且所有的叶子节点都在同一层上。其 特点 有:   (1)叶子节点只能出现在最下面一层   (2)非叶子节点度一定是2   (3)在同样深度的二叉树中,满二叉树的节点个数最多,节点个数为: 2 h − 1 2h−1 ,其中 h h 为树的深度。       1.3 完全二叉树:   若设二叉树的深度为 h h ,除第 h h 层外,其它各层 ( 1 ~ h − 1 ) (1~h−1) 的结点数都达到最大个数,第 h h 层所有的结点都连续集中在最左边,这就是 完全二叉树 。其具有以下 特点 :   (1)叶子节点可以出现在最后一层或倒数第二层。   (2)最后一层的叶子节点一定集中在左部连续位置。   (3)完全二叉树严格按层序编号。(可利用数组或列表进行实现,满二叉树同)   (4)若一个节点为叶子节点,那么编号比其大的节点均为叶子节点。    二、二叉树的相关性质   2.1 二叉树性质: