中序遍历

重构二叉树之前序遍历和中序遍历

我是研究僧i 提交于 2019-12-02 07:16:12
题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。 假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 例如输入前序遍历序列{1,2,4,7,3,5,6,8} 和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回 代码实现: /** * @param pre * 二叉树的前序遍历结果 * @param in * 二叉树的中序遍历结果 * @return root 重构完成的二叉树的根节点 */ public TreeNode reConstructBinaryTree(int[] pre, int[] in) { // 前序遍历或者中序遍历的结果已构建完, 递归退出 if (pre == null || in == null || pre.length == 0 || in.length == 0) { return null; } // 用前序遍历的结果的第一个元素, 构造二叉树的根节点 TreeNode root = new TreeNode(pre[0]); int i; // 在中序遍历的结果中,找出根节点pre[0]所在下标 for (i = 0; i < in.length; i++) { if (in[i] == pre[0]) { break; } } // 构建当前根节点的左子树时, 前序遍历的数组为pre[1..i]

二叉树的线索化思想解析与代码实现

雨燕双飞 提交于 2019-12-02 06:47:01
二叉树线索化 思想重于代码:写程序是为了验证思想,这里讲解部分比较多,还望耐心哈!! 二叉树线索化目的是想将二叉树的中序遍历不用递归方式实现,同时也充分的利用叶子结点的左右孩子空间,但是需额外引入一个标志,该标志用于判断该结点的左右孩子是线索连接的前驱后继还是直接连接左右孩子。并通过该链表将中序遍历的结点连成一条链,即遍历链表相当于二叉树的中序遍历。 问题:为什么要引入线索化这个概念? 1.对叶子的左右孩子的充分利用 2.当二叉树有大量结点时,需要进行很多次递归调用,需要消耗很大的栈空间。 3.可以直接访问当前结点的前驱后继,不需要重新从根节点往下再次遍历,效率高。 那么如何实现呢? 引入标志位 tag,一般使用枚举类型 enum{ Link,Thread }; Link表示孩子,Thread表示线索指向前驱后继 创建一个普通二叉树(即无线索化) 中序遍历二叉树进行线索化,线索化时需要引入一个辅助结点”pre”,这个结点左孩子一开始指向二叉树的根节点,右孩子指向空,我们知道在线索化时二叉树每个叶子都将被标志位Thread,指向他们的前驱后继,这时候考虑一个问题,在中序遍历时我们是无法知道当前结点的前驱或后继对应的是哪个结点,所以pre变量可以作为上一个结点的缓存。可以发现每一个叶子的前驱需要由pre指定,而后继需要在下一次(中序遍历的下一个结点)进行确定

LeetCode#二叉树的非递归遍历

依然范特西╮ 提交于 2019-12-02 02:35:47
二叉树的非递归遍历 **根据前序遍历访问的顺序,优先访问根结点,然后再分别访问左孩子和右孩子。即对于任一结点,其可看做是根结点,因此可以直接访问,访问完之后,若其左孩子不为空,按相同规则访问它的左子树;当访问其左子树时,再访问它的右子树。因此其处理过程如下: ** 对于任一结点P: 1)访问结点P,并将结点P入栈; 2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);若不为空,则将P的左孩子置为当前的结点P; 3)直到P为NULL并且栈为空,则遍历结束。 ** void preOrder2(BinTree *root) //非递归前序遍历 { stack<BinTree*> s; BinTree *p=root; while(p!=NULL||!s.empty()) { while(p!=NULL) { cout<<p->data<<""; s.push(p); p=p->lchild; } if(!s.empty()) { p=s.top(); s.pop(); p=p->rchild; } } } **根据中序遍历的顺序,对于任一结点,优先访问其左孩子,而左孩子结点又可以看做一根结点,然后继续访问其左孩子结点,直到遇到左孩子结点为空的结点才进行访问,然后按相同的规则访问其右子树。因此其处理过程如下:

二叉树的遍历

廉价感情. 提交于 2019-12-01 22:12:22
二叉树的中序遍历: 迭代: class Solution: def inorderTraversal(self, root: TreeNode) -> List[int]: res,stack = [],[] while True: while root: stack.append(root) root = root.left if not stack: return res node = stack.pop() res.append(node.val) root = node.right return res 递归: class Solution: def inorderTraversal(self, root: TreeNode) -> List[int]: res = [] def helper(root): if not root: return helper(root.left) res.append(root.val) helper(root.right) helper(root) return res 另: class Solution: def inorderTraversal(self, root: TreeNode) -> List[int]: f = self.inorderTraversal return f(root.left) + [root.val]

二叉树创立及遍历

六眼飞鱼酱① 提交于 2019-12-01 18:25:25
编写程序实现二叉树的创建,先序、中序、后序的递归遍历算法。在此基础上设计一个主程序完成如下功能: (1 )依次读入字符 “ABD∅∅E∅∅C∅FG∅∅H∅∅” , 按照先序建立二叉树T(∅表示空格); ( 2)先序递归遍历二叉树T,输出遍历序列; ( 3)中序递归遍历二叉树T,输出遍历序列; (4 )后序递归遍历二叉树 T,输出遍历序列。 #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define MAXSIZE 70 typedef struct BiTreeNode { char data; struct BiTreeNode *left; struct BiTreeNode *right; }BiTreeNode, *BiTree; void CreateBiTree(BiTree *T) { char val; scanf_s("%c", &val); if (val == '0') *T = NULL; //null表示为空枝 else { *T = (BiTree)malloc(sizeof(BiTreeNode)); (*T)->data = val; CreateBiTree(&(*T)->left); CreateBiTree(&(*T)->right); } } void

模拟76 题解

混江龙づ霸主 提交于 2019-12-01 15:05:31
A. 序列 观察部分分,可以得到一些奇怪的构造方法。 比如当$N=A*B$,直接将数按$A$的大小或$B$的大小分块就可以了 接着打表,发现似乎全部的情况都可以通过类似的方法构造出来。 只要对后面的部分分块,前面不足的部分不用分块。 B. 购物 奇妙的数的范围很宽泛,达到$[k,2k]$的程度。 显然的结论是:对于$[\lceil \frac{a_{max}}{2} \rceil,\sum \limits_{i=1}^{n}a_i]$的一切数,都是奇妙的。 所以可以拿到70分。 仔细想想,可以用一个类似背包的过程来进行这个$dp$。 首先将权值0加入数组$p$, 依次考虑$a_i$, 对于$p$中每一个数,在选$a_i$和不选的情况下分别加入数组$q$。 对数组$q$进行排序。 清空数组$p$。 如果$q_{i+1}已经大于当前$p$的最后一个值的两倍,那么加入$q_i$到$p$数组的末尾。 显然$p$数组的大小不会超过$2*log_2sum$,所以时间复杂度是正确的。 在加法的意义下,因为奇妙的数的区间达到$[k,2k]$, 对于加入一个非负数,相邻两个数会由$p_i$,$p_{i+1}$,变为$p_i+x$,$p_{i+1}+x$ 由于保证$p_i*2>p_{i+1}$,$p_i*2+x*2>p_{i+1}+x$是显然的。所以正确性是可以证明的。 最终考虑相邻两个数可以统计答案

*LeetCode-94 二叉树的中序遍历

╄→尐↘猪︶ㄣ 提交于 2019-12-01 09:50:24
问题: 中序遍历二叉树 分析: 1.递归解法 2.栈+循环    嵌套循环   内层循环一直判断当前节点有没有左节点,有就入栈,当前节点等于左节点,没有的话,就出栈打印,当前节点再等于右节点,然后回到开始进行循环判断右节点的左节点是不是空。 代码: import java.util.ArrayList; import java.util.List; import java.util.Stack; public class Solution { public List<Integer> inorderTraversal(TreeNode root) { List<Integer> listTree = new ArrayList<Integer>(); TreeNode cur = root; Stack s = new Stack(); while(!s.empty()||cur!=null){ while(cur!=null){ s.push(cur); cur = cur.left; } cur = (TreeNode) s.pop(); listTree.add(cur.val); cur = cur.right; } return listTree; } } 来源: https://www.cnblogs.com/gmzqjn/p/11676578.html

数据结构与算法之二叉树

馋奶兔 提交于 2019-12-01 09:32:12
树 树的概念 树(英语:tree)是一种抽象数据类型(ADT),用来模拟具有树状结构性质的数据集合。它是由n(n>=0)个有限节点组成一个具有层次关系的集合。把它叫做“ 树 ”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点: 当n=0时,为空树,在任何一棵空树中: 有且仅有一个特定的称为根(Root)的节点 当n>1时: 除根节点外,其余节点可分为m(m>0)个互不相交的有限集T1、T2、…、Tm,其中每一个集合本身又是一棵树,并且称为根的子树(SubTree)。 每个节点有零个或多个子节点; 没有父节点的节点称为根节点; 每一个非根节点有且只有一个父节点; 除了根节点外,每个子节点可以分为多个不相交的子树; 树的术语 节点的度 :一个节点含有的子节点的个数称为该节点的度。 B的子节点为D、E、F, 因此,节点B的度为3。 树的度 :一棵树中,最大的节点的度称为树的度。 最大的节点的度为B节点的度,因此该树的度为3。 叶节点 或 终端节点 :度为零的节点。 不能往下再分的节点:K、J、F、L、O、P。 父亲节点 或 父节点 :若一个节点含有子节点,则这个节点称为其子节点的父节点。 如:K的父节点为I。 孩子节点或子节点 :一个节点含有的子树的根节点称为该节点的子节点。 B的孩子节点或子节点为:D、E、F。 兄弟节点

树的总结(遍历,BST,AVL原型,练习题)

天涯浪子 提交于 2019-12-01 09:00:53
目录 树 一.抽象数据类型 二、二叉树的性质 三、活用树的遍历 四、BST树 五、AVL树 六、BST树和AVL树练习 树 一.抽象数据类型 1.顺序存储 使用数组存储 父亲索引为 n 左孩子 2*n 右孩子 2*n+1 2.链式存储 typedef struct TNode *Position; typedef Position BinTree; /* 二叉树类型 */ struct TNode{ /* 树结点定义 */ ElementType Data; /* 结点数据 */ BinTree Left; /* 指向左子树 */ BinTree Right; /* 指向右子树 */ }; 二、二叉树的性质 1.二叉树第i层最大结点数为:2^(i-1),i>=1 2.深度为k的二叉树最大结点总数为:2^k-1,k>=1 3.对任何非空二叉树T,若n0表示叶子结点个数、n2是度为2的非叶子结点个数,那么二者满足关系n0=n2+1 void PreOrderTraversal(BinTree BT){ if(BT){ printf("%d",BT->Data); PreOrderTraversal(BT->Left); PreOrderTraversal(BT->Right); } } 中序后序同理,把打印放在中间和后面,这里不加以赘述。 3.2.非递归 以链式中序为例 void

根据后序和中序遍历输出先序遍历

℡╲_俬逩灬. 提交于 2019-12-01 06:08:47
本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果。 输入格式: 第一行给出正整数 N( ≤ 3 0),是树中结点的个数。随后两行,每行给出 N个整数,分别对应后序遍历和中序遍历结果,数字间以空格分隔。题目保证输入正确对应一棵二叉树。 输出格式: 在一行中输出 Preorder: 以及该树的先序遍历结果。数字间有1个空格,行末不得有多余空格。 输入样例: 7 2 3 1 5 7 6 4 1 2 3 4 5 6 7 输出样例: Preorder: 4 1 3 2 6 5 7之前学递归,全排列、整数分解什么的都做不出来,也不想想,弄的自己原地停了一个星期。。。。现在想想,还是自己太着急。这个题用递归实现的,知道中序遍历和后序遍历,建树,然后输出先序遍历。递归思路和创建树一样,就是创建根节点,创建它的左孩子右孩子,多了参数限制 #include<iostream> #include<stdio.h> #include<stdlib.h> using namespace std; typedef int TElemType; typedef int Status; #define OK 1 #define ERROR 0 typedef struct BiTNode { TElemType data; struct BiTNode *lchild,*rchild;