后序遍历

二叉树遍历(递归、非递归)

喜你入骨 提交于 2020-01-27 04:51:59
1、递归遍历 1 void helper(TreeNode* root, vector<int>& res) { 2 if (root) { 3 res.push_back(root->val); 4 helper(root->left, res); 5 helper(root->right, res); 6 } 7 } 把3~5行按照访问顺序交换一下位置,就能实现前序遍历、中序遍历和后序遍历。 2、非递归遍历 非递归遍历可以用栈实现。 a. 前序遍历(144. Binary Tree Preorder Traversal) 前序遍历节点访问次序是 根-左-右 所以对于弹出的每一个节点,进栈顺序是先右孩子,再左孩子 1 class Solution { 2 public: 3 vector<int> preorderTraversal(TreeNode* root) { 4 vector<int> res; 5 stack<TreeNode*> stk; 6 if(root) 7 stk.push(root); 8 while (!stk.empty()) { 9 TreeNode *temp = stk.top(); 10 stk.pop(); 11 res.push_back(temp->val); 12 if (temp->right) 13 stk.push(temp-

二叉树遍历

ε祈祈猫儿з 提交于 2020-01-26 19:46:46
二叉树遍历 1.前序(先序):根 左 右 ==>A BDFE CGHI 2.中序:左 根 右 ==>D B EF A GH C I 3.后序:左 右 根 ==>DEFB GHIC A 错误笔记 :后序和中序都是从 左 ,这个左就是 最左边 这个数,不能单纯记为左下角这个数,我把他记成左下角这个数刚刚就产生了疑惑,图片里面这个D和E到底怎么安排,如果记为 最左边 就毫无疑惑是D。 遍历完左子树之后到了B结点这里,然后是到左下角,而不是最左边 4.层序:从上到下,从左到右 这个遍历的顺序是理解起来最简单的,但是代码实现起来却是最难的(个人观点),反正理解起来一定错不了, 从上到下,从左到右 。 A BC DEF GHI 代码实现 建立一个结构体链表来存储。 struct node { struct node * l ; //left struct node * r ; //right int data ; } ; 先序遍历: void xian ( struct node * t ) { if ( t == NULL ) return ; printf ( "%d" , t -> data ) ; //先输出结点data xian ( t -> l ) ; //遍历左子树 xian ( t -> r ) ; //遍历右子树 } 中序遍历: void zhong ( struct

递归示例(一):遍历二叉树

心已入冬 提交于 2020-01-26 18:46:30
最近做项目经常用到递归,刚开始很久没用,不太熟悉,现在研究了下,并写下了学习笔记及开发经验总结。 递归热身 一个算法调用自己来完成它的部分工作,在解决某些问题时,一个算法需要调用自身。如果一个算法直接调用自己或间接地调用自己,就称这个算法是递归的(Recursive)。根据调用方式的不同,它分为直接递归(Direct Recursion)和间接递归(Indirect Recursion)。 比如,在收看电视节目时,如果演播室中也有一台电视机播放的是与当前相同的节目,观众就会发现屏幕里的电视套有一层层的电视画面。这种现象类似于直接递归。 如果把两面镜子面对面摆放,便可从任意一面镜子里看到两面镜子无数个影像,这类似于间接递归。 一个递归算法必须有两个部分:初始部分(Base Case)和递归部分(Recursion Case)。初始部分只处理可以直接解决而不需要再次递归调用的简单输入。递归部分包含对算法的一次或多次递归调用,每一次的调用参数都在某种程度上比原始调用参数更接近初始情况。 函数的递归调用可以理解为:通过一系列的自身调用,达到某一终止条件后,再按照调用路线逐步返回。递归是程序设计中强有力的工具,有很多数学函数是以递归来定义的。 如大家熟悉的阶乘函数,我们可以对n!作如下定义:f(n)= 1 (n=1) n*f(n-1) (n>=2) 一个算法具有的特性之一就是有穷性

用JavaScript刷LeetCode的正确姿势

爷,独闯天下 提交于 2020-01-25 18:09:52
虽然很多人都觉得前端算法弱,但其实 JavaScript 也可以刷题啊!最近两个月断断续续刷完了 leetcode 前 200 的 middle + hard ,总结了一些刷题常用的模板代码。 走过路过发现 bug 请指出,拯救一个辣鸡(但很帅)的少年就靠您啦! 常用函数 包括打印函数和一些数学函数。 const _max = Math.max.bind(Math); const _min = Math.min.bind(Math); const _pow = Math.pow.bind(Math); const _floor = Math.floor.bind(Math); const _round = Math.round.bind(Math); const _ceil = Math.ceil.bind(Math); const log = console.log.bind(console); //const log = _ => {} log 在提交的代码中当然是用不到的,不过在调试时十分有用。但是当代码里面加了很多 log 的时候,提交时还需要一个个注释掉就相当麻烦了,只要将 log 赋值为空函数就可以了。 举一个简单的例子,下面的代码是可以直接提交的。 // 计算 1+2+...+n // const log = console.log.bind(console);

已知树的前序和中序遍历,求后序遍历;后序和中序,求前序

∥☆過路亽.° 提交于 2020-01-25 13:29:48
首先需要说明的是,网上不知道为什么很多误传,说给定前序、中序和后序中的两个,可以唯一确定另一个,显然这是错误的。给定前序和后序,是无法确定中序的,一个简单的例子就是只有两个节点的树,前序和后序给定,中序无法确定。 代码如下: 1 /* 2 * Copyright (c) 2014 3 * All Rights Reserved. 4 * author: laohaizi 5 */ 6 7 #include <iostream> 8 #include <string> 9 #include <string.h> 10 #include <stdio.h> 11 using namespace std; 12 13 typedef struct _NODE 14 { 15 char name; 16 struct _NODE *left,*right; 17 }NODE; 18 19 char *preorder="abcdefg"; 20 char *inorder="cbedagf"; 21 //char *inorder="abcdefg"; 22 char *postorder="cedbgfa"; 23 const int preorder_len = strlen(preorder); 24 const int inorder_len = strlen(inorder);

二叉树遍历基础 -- 递归与非递归的实现方法

 ̄綄美尐妖づ 提交于 2020-01-25 06:19:57
之前也写过不少关于二叉树的东西了,但是总体来说,二叉树还是一个很绕的东西,所以单独择出来写一篇笔记,之前也没计划什么的,就想到什么写什么吧。不过该篇文章的 主要内容是关于二叉树的三种遍历(前序、中序、后序)不同的实现方式(递归与非递归) 。 首先,我觉得很有必要去彻底理解一下递归。 (1)递归的主体大概分两部分:递归停止的条件、递归内容。 (2)递归应用的实例:这个超级多,就比如最典型的 斐波那契数列 。个人认为,可以用循环实现的,递归基本上都可以实现,但有时递归的效率不如循环。 (3)递归又分为单递归与多递归(二叉树的三种遍历递归方法均用到了双递归!) 根据上面的三点,举个例子先。 假设当x=0时,F(x)=1;否则F(x)=F(n-1)*n。这个时候就可以用递归了,代码实现如下。 class Solution{ public int F(int n) { //递归停止条件 if (n == 0) { return 1; } //递归内容 else { return F(n - 1) * n; } } } 代码分析一下如下: 二叉树的三种遍历:前序(根左右)、中序(左根右)、后序(左右根) 首先看 三种遍历的递归实现方法 。(特点:代码清晰,量少,但不易理解) // (1)前序遍历 public TreeNode PreOrder(TreeNode pRoot) { /

树遍历和非递归

谁说胖子不能爱 提交于 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

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