后序遍历

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

妖精的绣舞 提交于 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

python实现基础的数据结构(二)

非 Y 不嫁゛ 提交于 2019-11-29 18:33:55
本文涉及到的代码均已放置在我的github中 --> 链接 python实现基础的数据结构(一) python实现基础的数据结构(二) python实现基础的数据结构(三) python语法较为简洁,正好最近在复习数据结构,索性就用python去实现吧😀 本文实现的有线性表、栈、队列、串、二叉树、图、排序算法。参照教材为 数据结构(C语言版)清华大学出版社 ,还有网上的一些大神的见解。由于包含代码在内,所以内容很多,分了几篇,话不多说,我们直接步入正题🙈 注:本文实验环境:Anaconda 集成 python 3.6.5 ( 故代码为 python3 ) 由于本文代码过多,故每一步不做太详细的介绍,我尽量在代码中解释细节,望体谅 串 串是由零个或者多个字符组成的优先序列,一般记为是s = ‘a1a2…an’ ,python对字符串的操作已经比较成熟和简单,所以我们这里着重介绍串的模式匹配算法,这就不得不提KMP匹配算法,这种算法和正则表达式有类似之处,一个用了DFA的思想,一个用了NFA的思想。 KMP算法的思想是,当匹配失败时,可以利用已经知晓的一部分文本内容,避免从头开始重新匹配。这个匹配的过程可以使用有限状态自动机(DFA)。可以看看 这位大神 的描述。 每当一趟匹配过程中出现字符比较不等时,不需要回溯I指针,而是利用已经的带的“部分匹配

二叉树

大兔子大兔子 提交于 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 二叉树性质:   

树、图、排序查找重要算法(960算法)

老子叫甜甜 提交于 2019-11-29 17:09:09
设计求T的WPL的算法:   (1) .给出二叉树结点的数据类型定义;   (2) .给出C语言描述算法;   【 1 】: typedef struct node { int weight; struct node *left,*right; //指向结点左右子女的指针 }BiNode,*BiTree;   【 2 】: int WPL=0; void inorder(BiTree bt,level lv) //bt是二叉树,lv是结点的层次,初值为1 { if(bt) {inorder (bt->left,lv+1); //中序遍历左子树 if(bt->left==null &&bt->right==null) //判断该结点是否为叶子 WPL+=(lv-1)*bt->weight; //累加结点带权路径长度 inorder(bt->right,lv+1); } } 【先序遍历】 NLR (递归) void PreOrder(BiTree T){ if(T!=NULL){ visit(T); //访问根结点 PreOrder(T->lchild); //递归遍历左子树 preOrder(T->rchild); } } 【中序遍历】 LNR (递归) void InOrder(BiTree T){ if(T!=NULL){ InOrder(T->lchild); visit(T)

前序遍历和中序遍历树构造二叉树

白昼怎懂夜的黑 提交于 2019-11-29 15:39:41
根据中序遍历和后序遍历树构造二叉树 样例 样例 1: 输入:[],[] 输出:{} 解释: 二叉树为空 样例 2: 输入:[1,2,3],[1,3,2] 输出:{2,1,3} 解释: 二叉树如下 2 / \ 1 3 注意事项 你可以假设树中不存在相同数值的节点 /** * Definition of TreeNode: * class TreeNode { * public: * int val; * TreeNode *left, *right; * TreeNode(int val) { * this->val = val; * this->left = this->right = NULL; * } * } */ class Solution { public: /** *@param preorder : A list of integers that preorder traversal of a tree *@param inorder : A list of integers that inorder traversal of a tree *@return : Root of a tree */ TreeNode * buildTree(vector<int> &preorder, vector<int> &inorder) { // write your code

二叉树算法题

断了今生、忘了曾经 提交于 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-

ArrayList循环遍历并删除元素的常见陷阱

自古美人都是妖i 提交于 2019-11-29 10:28:54
在工作和学习中,经常碰到删除ArrayList里面的某个元素,看似一个很简单的问题,却很容易出bug。不妨把这个问题当做一道面试题目,我想一定能难道不少的人。今天就给大家说一下在ArrayList循环遍历并删除元素的问题。首先请看下面的例子: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import java.util.ArrayList; public class ArrayListRemove { public static void main(String[] args) { ArrayList<String> list = new ArrayList<String>(); list.add("a"); list.add("b"); list.add("b"); list.add("c"); list.add("c"); list.add("c"); remove(list); for (String s : list) { System.out.println("element : " + s); } } public static void remove(ArrayList<String> list) { // TODO: } } 如果要想删除list的b字符,有下面两种常见的错误例子: