中序遍历

树遍历和非递归

谁说胖子不能爱 提交于 2020-01-25 05:17:13
利用随机函数产生 80 个 ( 不大于 200 且各不相同的 ) 随机整数,用这些整数来生成一棵二树,分别对二叉树进行先序遍历,中序遍历和后序列遍历输出树中结点元素序列。注意:先序遍历输出要求采用非递归来实现。 ( 2 )程序实现的基本思想 1. 建立合适的二叉树 程序是以 图 1.1 的形式建立的。 2. 前序遍历是以 stack 栈和指针左右子女实现的。 3. 前序遍历,中序遍历,后序遍历分别用了递归实现。 4. 如建立二叉树,其中随机产生的数值是( 因为 80 个数比较多,所以就以 #define Max_size 10 ,若要以 80 个数,可 #define Max_size 10 改成 #define Max_size 80 ): 106 199 95 144 102 164 26 96 87 168 由以上数值可以建立出以下的树: 图 1.2 由图 1.2 可得出他们的前序,中序和后序。 前序序列: 106 95 26 87 102 96 199 144 164 168 中序序列: 26 87 95 96 102 106 144 164 168 199 后序序列: 87 26 96 102 95 168 164 144 199 106 ( 3 )系统流程图 程序步骤: #include "stdio.h" #include "conio.h" #define Max

前、中、后序遍历二叉树

喜你入骨 提交于 2020-01-25 01:11:19
后序遍历 后序遍历首先遍历左子树,然后遍历右子树,最后访问根结点,在遍历左、右子树时,仍然先遍历左子树,然后遍历右子树,最后遍历根结点。即: 若 二叉树 为空则结束返回, 否则: (1)后序遍历左子树 (2)后序遍历右子树 (3)访问根结点 如右图所示 二叉树 后序遍历结果:DEBFCA 中序遍历 中序遍历首先遍历左子树,然后访问根结点,最后遍历右子树。若 二叉树 为空则结束返回,否则: (1)中序遍历左子树 (2)访问根结点 (3)中序遍历右子树 如右图所示二叉树,中序遍历结果:DBEAFC 前序遍历 前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问 根结点 ,然后遍历左子树,最后遍历右子树。 若 二叉树 为空则结束返回,否则: (1)访问根结点。 (2)前序遍历左子树 。 (3)前序遍历右子树 。 前序遍历 需要注意的是:遍历左右子树时仍然采用前序遍历方法。 如右图所示 二叉树 前序遍历结果:ABDECF 已知后序遍历和中序遍历,就能确定前序遍历。 来源: CSDN 作者: 这瓜保熟么 链接: https://blog.csdn.net/luzhensmart/article/details/104062758

算法 :重建二叉树

廉价感情. 提交于 2020-01-24 23:30:39
** 题目: 输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字 ** public static TreeNode construct(int[] preorder,int[] inorder){ if(preorder == null || inorder == null){ return null; } return constructCore(preorder,0,preorder.length-1,inorder,0,inorder.length-1); } private static TreeNode constructCore(int[] preorder, int startPre, int endPre, int[] inorder, int startIn, int endIn) { if(startPre < endPre || startIn < endIn){ return null; } TreeNode root = new TreeNode(startPre); for(int i = startIn ; i < endIn ; i++){ if(preorder[startPre] == inorder[i]){ //找到之后,分别对左子树和右子树进行递归算法,重复此步骤 root

Morris 遍历

心已入冬 提交于 2020-01-24 06:54:31
1. 二叉树遍历 树是最重要的数据结构之一,而树的遍历是树最基本的操作。 二叉树的遍历一般来说有三种遍历次序: 前序遍历 中序遍历 后序遍历 而这三种遍历次序都可以采用 递归 和 非递归 的方式来完成。 就时间、空间的复杂度来讲,因为非递归需要借助额外的 Stack 来完成操作,所以递归和非递归的时间复杂度都是 O(n) , O(logn) 。 那么有没有另外的不同的二叉树遍历方法,在时间或空间能做到更优的呢?答案是: Morris 遍历 。 由于在遍历的时候,我们需要记住某种遍历次序的的 后驱 或者 前驱 结点,常见的递归和非递归都是采用 栈 的方式完成这个过程,有没有内部空间来记录这些后驱或者前驱结点呢?有,那就是叶结点的左,右孩子结点,因为叶结点的两个孩子结点都是空指针,如果利用好这些空间,我们就可以在 O(1) 的空间完成遍历。 利用叶结点的左、右孩子指向遍历的前驱或者后驱结点,这些指针叫做 线索 ,对应的二叉树叫做 线索二叉树 。 Morris遍历 是使用线索二叉树进行中序遍历的一种实现 ,其可以在 O(n) 的时间, O(1) 的空间完成遍历, 对其稍加修改可以推广到 先序、后序遍历 ,其遍历过程包含三个部分: 创建指向 中序后驱 结点的线索; 遍历输出结点; 删除线索,恢复树的结构; 2. Morris 中序遍历 Morris 中序遍历过程如下:

二叉树的前中后序遍历

穿精又带淫゛_ 提交于 2020-01-24 02:21:21
前中后序遍历的递归方式。 其实,前中后序的遍历,走的路径是一样的,只是访问结点的时间不同而已。 非递归进行前中后序遍历(使用栈) 题目描述: List preorderTraversal(TreeNode root) List inorderTraversal(TreeNode root) List postorderTraversal(TreeNode root) 题目链接: https://leetcode-cn.com/problems/binary-tree-preorder-traversal/ https://leetcode-cn.com/problems/binary-tree-inorder-traversal/ https://leetcode-cn.com/problems/binary-tree-postorder-traversal/ 1.前序遍历 public List < Integer > preorderTraversal ( TreeNode root ) { List < Integer > list = new LinkedList < > ( ) ; //迭代解决 使用栈 LinkedList < TreeNode > stack = new LinkedList < > ( ) ; TreeNode tmp = root ; while

Morris遍历遍历二叉树

孤街浪徒 提交于 2020-01-22 22:51:29
遍历二叉树的递归方法使用了函数栈,非递归方法使用了申请的栈, 两者的额外空间都与树的高度有关,所以空间复杂度为O(h),h为二叉树的高度。 可以使用二叉树叶子节点中大量指向null的指针实现空间复杂度O(1)的遍历。 Morris遍历的实质就是避免使用栈结构,让下层到上层有指针, 具 体是通过让底层节点指向null的空闲指针指回上层的某个节点,从而完成下层到上层的移动。 先序中序后序主要基于两个主要步骤,然后输出的位置有所不同,以中序遍历为例。 中序遍历: 1、假设当前子树的头节点为h,让h的左子树中最右节点的right指针指向h, 然后h的左子树继续步骤1的处理过程,直到遇到某一个节点没有左子树时记为node,进入步骤2。 2、从node开始通过每个节点的right指针进行移动并以此打印,假设移动到的节点为cur。 对每一个cur节点都判断cur节点的左子树中最右节点是否指向cur。 Ⅰ 如果是,令cur节点的左子树中最右节点的right指针指向null,即恢复树的本来面貌, 然后打印cur,继续通过cur的right指针移动到下一个节点。重复步骤2。 Ⅱ 如果不是,以cur为头的子树重回步骤1执行。 public void morrisIn(TreeNode root) { if (root == null) return; TreeNode cur1 = root;

LeetCode 144. 二叉树的前序遍历(Binary Tree Preorder Traversal)

一世执手 提交于 2020-01-22 22:48:55
144. 二叉树的前序遍历 144. Binary Tree Preorder Traversal 题目描述 给定一个二叉树,返回它的 前序 遍历。 LeetCode 144. Binary Tree Preorder Traversal 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,2,3] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? Java 实现 Iterative Solution import java.util.LinkedList; import java.util.List; import java.util.Stack; class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> result = new LinkedList<>(); if (root == null) { return result; } Stack<TreeNode> stack = new Stack<>(); stack.push(root); while (

前序与中序遍历序列构造二叉树 中序与后序遍历序列构造二叉树

对着背影说爱祢 提交于 2020-01-22 07:22:29
105. 从前序与中序遍历序列构造二叉树 根据前序遍历和中序遍历,我们可以发现前序遍历的第一个元素就为根元素,在中序遍历中找到这个元素,那么中序遍历中左边为根元素的左子树,右边为右子树,依次递归。 /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public TreeNode buildTree(int[] preorder, int[] inorder) { int len1 = preorder.length-1; int len2 = inorder.length-1; TreeNode root = bulidTree(preorder,0,len1,inorder,0,len2); return root; } public TreeNode bulidTree(int[] preorder, int start1,int end1,int[] inorder,int start2, int end2){ if(start1>end1 || start2>end2){ return

LeetCode--105--从前序与中序遍历序列构造二叉树(python)

こ雲淡風輕ζ 提交于 2020-01-22 06:49:52
根据一棵树的前序遍历与中序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 例如,给出 前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9,3,15,20,7] 返回如下的二叉树: 3 / \ 9 20 / \ 15 7 1 class Solution: 2 def buildTree(self, preorder, inorder): 3 """ 4 :type preorder: List[int] 5 :type inorder: List[int] 6 :rtype: TreeNode 7 """ 8 def helper(in_left = 0, in_right = len(inorder)): 9 nonlocal pre_idx 10 # if there is no elements to construct subtrees 11 if in_left == in_right: 12 return None 13 14 # pick up pre_idx element as a root 15 root_val = preorder[pre_idx] 16 root = TreeNode(root_val) 17 18 # root splits inorder list 19 # into left

根据前序遍历和中序遍历的结果重构二叉树LeetCode 95

只愿长相守 提交于 2020-01-22 05:25:16
题目描述 https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ 根据一棵树的前序遍历与中序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9,3,15,20,7] 返回如下的二叉树: 3 / \ 9 20 / \ 15 7 思路 首先我们在上一篇文章中解释了前序遍历和中序遍历的含义,因为是树的结构,一般都是用递归来实现。 用数学归纳法的思想就是,假设最后一步,就是root的左右子树都已经重建好了,那么我只要考虑将root的左右子树安上去即可。 根据前序遍历的性质,第一个元素必然就是root,那么下面的工作就是如何确定root的左右子树的范围。 根据中序遍历的性质,root元素前面都是root的左子树,后面都是root的右子树。那么我们只要找到中序遍历中root的位置,就可以确定好左右子树的范围。 简单来说就是当前前序遍历的结果,第一个元素必然是当前节点的值,而对于中序遍历来说,当前节点值的位置的前面都是左子树的值,后面都是右子树的值,所以根据这个思想,重新构建二叉树。 实现代码 /** * Definition for a binary tree