中序遍历

遍历线索化二叉树

爷,独闯天下 提交于 2020-01-28 18:30:08
遍历线索化二叉树 常规的线索化方式 采用递归地调用的方式,判定条件是当前指针的左子树是否为空 代码实现: public void midOrder ( ) { if ( this . left != null ) { this . left . midOrder ( ) ; } System . out . println ( this ) ; if ( this . right != null ) { this . right . midOrder ( ) ; } } 对比: 但是对二叉树进行线索化之后,不存在空的左右指针,但是单独设置每一个指针的类型,故而条件修改为指针的类型。 代码实现 我的代码 public void midLIst ( ) { if ( this . getLeftType ( ) != 1 ) { this . getLeft ( ) . midLIst ( ) ; } System . out . print ( this + " " ) ; if ( this . getRightType ( ) != 1 ) { this . getRight ( ) . midLIst ( ) ; } } 问题分析与总结: 出现空指针异常,因为到最后一个节点时,其右指针是没有改变,仍旧为null,并且没有对其值进行修改,故而会出现空指针。 代码修改 public

重建二叉树

对着背影说爱祢 提交于 2020-01-28 05:07:09
题目:重建二叉树 题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。 思路 前序遍历:中左右 中序遍历:左中右 根据pre[0]=vin[i]找出根(mid)的位置,递归左右子树 #include<iostream> #include<vector> #include<queue> #include<stack> using namespace std; struct TreeNode{ int val; TreeNode *left; TreeNode *right; TreeNode(int x): val(x), left(NULL), right(NULL){ } }; class Solution{ public: // 思路:递归左右子树,找出左右的pre和vin TreeNode *reConstructBinaryTree(vector<int> pre, vector<int> vin){ int mid, size=pre.size(); if(size==0) return NULL; TreeNode *root = new TreeNode(pre[0]); //

二叉树遍历 递归非递归

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

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

喜你入骨 提交于 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-

leetcode-二叉树的中序遍历

烈酒焚心 提交于 2020-01-27 00:09:33
class Solution { private List<Integer> retlist = new LinkedList<>(); public List<Integer> inorderTraversal(TreeNode root) { //中序遍历,左臂入栈 TreeNode cur = root; Stack<TreeNode> stack = new Stack<>(); while(cur!=null || !stack.isEmpty()){ if(cur!=null){ stack.add(cur); cur = cur.left; } else{ cur = stack.pop(); retlist.add(cur.val); cur = cur.right; } } return retlist; } } 迭代写法,核心思路就是和以往只有一个stack作为判断依据不同,这次有两个判断依据TreeNode cur和stack。 如果cur不为空,加入stack,将指针指向left,如果为空pop一个,加入返回值,然后指针指向右边 来源: CSDN 作者: dogndaxiaodong 链接: https://blog.csdn.net/weixin_41327340/article/details/104089774

二叉树遍历

ε祈祈猫儿з 提交于 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) { /