二叉树遍历

二叉树算法题

断了今生、忘了曾经 提交于 2019-11-29 15:20:30
二叉树层次遍历 //思路 特殊情况 ,根节点为null,深度为0,return 0 借助队列,队列储存每一层的所有节点, 先保存数组长度,用于控制依次遍历循环——遍历每一个节点保存值,该节点的所有子结点从队尾入队,访问过的节点从头出队 注意——需要先把width存下来,用于for循环的结束标志,因为for循环里面直接操作了queue,不能去都不敢动态获取 队列初始值为root,对每一层都要进行上述遍历——while循环控制,队列空代表叶节点这一层遍历完成,此时遍历结束,退出循环 每次循环开始前初始化一个curNodes储存该层所有节点,每次循环结束,将curNodes压入result var levelOrder = function(root) { if (root === null) return []; //空树 var result = [], queue = [root]; while (queue.length) { let width = queue.length; //需要先把width存下来,用于for循环,for循环里面直接操作了数组 let curNodes = []; for (let i = 0; i < width; i++) { let node = queue.shift(); curNodes.push(node.val); node.left ?

数据结构(四)二叉树

半城伤御伤魂 提交于 2019-11-29 12:29:17
一、树 Vector和List都有明显的弱点,都无法兼顾动态和静态操作的高效性。 Tree可以认为将Vector和List的优点结合了起来,可以认为是列表的列表List<List>,半线性结构。 应用 层次关系的表示 从数学上看,树是一类特殊的图,联通无环图。 树由一组顶点(vertex)以及连接于期间的若干条边(edge)组成。 在计算机科学中 ,会指定某个特定的顶点,称之为根(root) 在指定了根之后,我们称该树为 有根树(rooted tree) 从程序实现的角度,我更多地将顶点(vertex)称作节点(node) 通过彼此嵌套,小型的有根树可以变成大型的有根树 对于任何一组有根树,可以通过引入新的顶点,在新的顶点和此前各有根树的树根之间引入对应的一条连边,从而构成规模更大的一棵有根树。 r i 称作r的孩子(child),r i 之间互称 兄弟(sibling) ,r为其 父亲(parent) d=degree(r)为r的(出) 度 (degree) 某一节点v孩子的总数,称作该节点的度数或度(degree),无孩子的节点称为叶节点(leaf node),包括根在内的其余节点皆为内部节点(internal node)。 n为顶点数,e为边数, 任何一棵树所含的边数,恰好等于所有顶点的度数之和,也等于顶点总数减1,一棵树的边数与顶点数目是同阶的。 树是 无环连通图

二叉树的遍历

那年仲夏 提交于 2019-11-29 11:10:28
目录 一、二叉树的遍历 1.1 先序遍历 1.2 中序遍历 1.3 后序遍历 1.4 小结 二、二叉树的非递归遍历 2.1 中序遍历非递归遍历算法 2.2 先序遍历的非递归遍历算法 三、层序遍历 3.1 队列实现 四、实际应用 4.1 遍历二叉树的应用:输出二叉树中的叶子节点 4.2 求二叉树的高度 4.3 二元运算表达式树及其遍历 4.4 由两种遍历序列确定二叉树 一、二叉树的遍历 1.1 先序遍历 遍历过程为: 访问 根结点 先序 遍历其左子树; 先序 遍历其右子树。 /* c语言实现 */ void PreOrderTraversal (BinTree BT) { if (BT) { printf("%d", BT->Data); PreOrderTraversal(BT->Left); PreOrderTraversal(BT->Right); } } 先序遍历: A (B D F E)(C G H I) 1.2 中序遍历 遍历过程为: 中序 遍历其 左子树 ; 访问 根节点 ; 中序 遍历其 右子树 。 /* c语言实现 */ void InOrderTraversal (BinTree BT) { if (BT) { InOrderTraversal(BT->Left); printf("%d", BT->Data); InOrderTracersal(BT-

二叉树的递归与非递归遍历

為{幸葍}努か 提交于 2019-11-29 08:18:53
二叉树的递归与非递归遍历 前序遍历二叉树 递归遍历 非递归遍历 中序遍历二叉树 递归遍历 非递归遍历 后序遍历二叉树 递归遍历 非递归遍历 将二叉树遍历的结果保存到vector中返回。 递归遍历代码简短,也相对容易理解,此不赘述。咱们重点来看一下非递归遍历。 前序遍历二叉树 递归遍历 void preORecursive(TreeNode* pRoot, vector<int>& vec) { if(pRoot == NULL) return; vec.push_back(pRoot->val); preORecursive(pRoot->left, vec); preORecursive(pRoot->right, vec); } vector<int> preOrderRecursive(TreeNode* pRoot) { vector<int> vec; if(pRoot == NULL) return vec; preORecursive(pRoot, vec); return vec; } 非递归遍历 思想: 栈后法,右左子孩子入栈法 ///栈后法,右左子孩子入栈法 vector<int> preOrder(TreeNode* pRoot) { vector<int> vec; stack<TreeNode*> sta; if(pRoot) { vec.push

二叉树遍历(前、中、后序及层序遍历)

倾然丶 夕夏残阳落幕 提交于 2019-11-29 06:57:37
二叉树的遍历 所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个节点均做一次且仅做一次的访问。访问节点所做的操作依赖于具体的应用问题。遍历是二叉树上最重要的运算之一。是二叉树上进行其它运算的基础。 如何将所有节点都遍历打印出来?经典的方法有三种:前序遍历、中序遍历、后序遍历。除此之外,还有按层遍历。其中,前、中、后序表示的是节点和它左右子树节点遍历打印的先后顺序。 前序遍历是指,对树中的任意节点,先打印这个节点本身,然后再打印它的左子树,最后打印它的右子树。 中序遍历是指,对树中的任意节点,先打印它的左子树,然后再打印这个节点本身,最后打印它的右子树。 后序遍历是指,对树中的任意节点,先打印它的左子树,然后再打印它的右子树,最后打印这个节点本身。 层次遍历是指,从第一层(根节点)开始,从上到下一层一层遍历,同层之间按从左到右的顺序依次遍历节点。 实际上,二叉树的前、中、后序遍历就是一个递归的过程。比如,前序遍历就是先打印根节点,然后再递归的打印左子树,最后递归的打印右子树。 二叉树的前、中、后序遍历的递归实现: /** Java版 * public class TreeNode{ * int val; * TreeNode left; * TreeNode right; * TreeNode(int x){ val = x; } */ // 前序遍历 public

二叉树

旧巷老猫 提交于 2019-11-29 05:11:54
前言 树是数据结构中的重中之重,尤其以各类二叉树为学习的难点。一直以来,对于树的掌握都是模棱两可的状态,现在希望通过写一个关于二叉树的专题系列。在学习与总结的同时更加深入的了解掌握二叉树。本系列文章将着重介绍一般二叉树、完全二叉树、满二叉树、 线索二叉树 、 霍夫曼树 、 二叉排序树 、平衡二叉树、红黑树、B树。希望各位读者能够关注专题,并给出相应意见,通过系列的学习做到心中有“树”。 1 重点概念 1.1 结点概念 结点是数据结构中的基础,是构成复杂数据结构的基本组成单位。 1.2 树结点声明 本系列文章中提及的结点专指树的结点。例如:结点A在图中表示为: 2 树 2.1 定义 树(Tree)是n(n>=0)个结点的有限集。n=0时称为空树。在任意一颗非空树中: 1)有且仅有一个特定的称为根(Root)的结点; 2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1、T2、......、Tn,其中每一个集合本身又是一棵树,并且称为根的子树。 此外,树的定义还需要强调以下两点: 1)n>0时根结点是唯一的,不可能存在多个根结点,数据结构中的树只能有一个根结点。 2)m>0时,子树的个数没有限制,但它们一定是互不相交的。 示例树: 图2.1为一棵普通的树: 图2.1 普通树 由树的定义可以看出,树的定义使用了递归的方式。递归在树的学习过程中起着重要作用

【树论】求先序遍历

僤鯓⒐⒋嵵緔 提交于 2019-11-29 02:22:05
原题传送门 题目 题目描述 给出一棵二叉树的中序与后序排列。求出它的先序排列。(约定树结点用不同的大写字母表示)。 输入输出格式 输入格式: 2行,均为大写字母组成的字符串,表示一棵二叉树的中序与后序排列。 输出格式: 1行,表示一棵二叉树的先序。 思路 首先,一点基本常识,给你一个后序遍历,那么最后一个就是根(如ABCD,则根为D)。 因为题目求先序,意味着要不断找根。 中序ACGDBHZKX,后序CDGAHXKZB,首先可找到主根B; 那么我们找到中序遍历中的B,由这种遍历的性质,可将中序遍历分为ACGD和HZKX两棵子树, 那么对应可找到后序遍历CDGA和HXKZ(从头找即可) 从而问题就变成求1.中序遍历ACGD,后序遍历CDGA的树 2.中序遍历HZKX,后序遍历HXKZ的树; 接着递归,按照原先方法,找到1.子根A,再分为两棵子树2.子根Z,再分为两棵子树。 就按这样一直做下去(先输出根,再递归); 模板概括为step1:找到根并输出 step2:将中序,后序各分为左右两棵子树; step3:递归,重复step1,2; Code #include<cstdio> #include<iostream> #include<cstring> using namespace std; void beford(string in,string after){ if (in

二叉树遍历(非递归版)——python

久未见 提交于 2019-11-28 22:27:17
二叉树的遍历分为广度优先遍历和深度优先遍历 广度优先遍历 (breadth first traversal):又称层次遍历,从树的根节点(root)开始,从上到下从从左到右遍历整个树的节点。 深度优先遍历( depth first traversal):对于一颗二叉树,深度优先遍历是沿着树的深度遍历树的节点,尽可能深的搜索树的分支。深度优先遍历有重要的三种方法。这三种方式常被用于访问树的节点,它们之间的不同在于访问每个节点的次序不同。这三种遍历分别叫做 先序遍历 (preorder):根节点->左子树->右子树, 中序遍历 (inorder):左子树->根节点->右子树,和 后序遍历 (postorder):左子树->右子树->根节点。这三种都是递归方式实现对一整个二叉树遍历的哦。 代码(非递归版) class TreeNode: def __init__(self, x): self.val = x self.left = None self.right = None class Trees: #根据前序和中序列表来重建二叉树 def reConstructBinaryTree(self, pre, tin): # write code here if len(pre) == 0: return None if len(pre) == 1: return TreeNode(pre

二叉树(二叉树的性质及遍历)

☆樱花仙子☆ 提交于 2019-11-28 19:54:58
一、二叉树的性质 在二叉树的第 i 层上至多有 2 i-1 个节点。 深度为 k 的二叉树至多有 2 k -1 个节点。 对任意一棵二叉树 T ,若终端节点数为 n 0 ,而其度数为 2 的节点为 n 2 ,则 n 0 =n 2 +1。 具有 n 个节点的完全二叉树的深度为 。 二、单链表结点的存储结构描述 typedef struct Node { ElemType data; struct Node *next; }Node,*LinkList; LinkList 和 Node * 同为结构指针类型,这两种类型是等价的。通常习惯上用 LinkList 说明指针变量,强调它是某个单链表的头指针变量。例如,使用定义 LinkList L, 则 L 为单链表的头指针,从而提高程序的可读性。用 Node* 来定义指向单链表中结点的指针,例如, Node *p, 则 p 为指向单链表中结点的指针变量。 三、二叉树的遍历方式 先序遍历:根、左、右 中序遍历:左、根、右 后序遍历:左、右、根 #include <iostream> #include <malloc.h> using namespace std; //二叉树的节点 typedef struct BiTNode { char ch;; struct BiTNode *lchild;//左孩子 struct BiTNode

二叉树及遍历总结

删除回忆录丶 提交于 2019-11-28 18:42:57
前言 由于最近一直在忙目标检测这块的项目,一直没有时间静下心来总结经典算法之一:二叉树。下面我会给大家介绍二叉树的定义以及其应用,方便大家加深对该算法的理解。 1. 二叉树 二叉树 是一种特殊的树,它具有以下 特点 : 1.树中每个节点最多只能有两棵树,即每个节点的度最多为2。    2.二叉树的子树有左右之分,即 左子树 与 右子树 ,次序不能颠倒。    3.二叉树即使只有一个子树时,也要区分是左子树还是右子树。 2. 二叉树的遍历 以下遍历以该二叉树为例: 2.1 前序遍历 思想 :先访问根节点,再先序遍历左子树,然后再先序遍历右子树。总的来说是根—左—右.上图先序遍历结果为为:1,2,4,8,9,5,3,6,7 2.2 中序遍历 思想 :先中序访问左子树,然后访问根,最后中序访问右子树。总的来说是左—根—右,上图中序遍历结果为为:8,4,9,2,5,1,6,3,7 2.3 后序遍历 思想 :先后序访问左子树,然后后序访问右子树,最后访问根。总的来说是左—右—根,上图后序遍历结果为为:8,9,4,5,2,6,7,3,1 2.4 层次遍历(宽度优先遍历) 思想 :利用 队列 ,依次将根,左子树,右子树存入队列,按照 队列 的 先进先出 规则来实现层次遍历。上图后序遍历结果为为:1,2,3,4,5,6,7,8,9 2.5 深度优先遍历 思想 :利用 栈 ,先将根入栈,再将根出栈