后序遍历

**LeetCode-145二叉树后序遍历

旧时模样 提交于 2019-12-01 09:55:54
问题: 后序遍历二叉树 分析:非递归后序遍历二叉树。直接后序遍历的话会很麻烦,所以我们要想一些精妙的方法,将后序遍历改成先序遍历并满足以下两个条件即可。 1.使用链表头插法来进行先序遍历。 2.先遍历右子树再遍历左子树即可(借助栈实现,先将左节点压栈,再将右节点压栈)。 代码: /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public List<Integer> postorderTraversal(TreeNode root) { LinkedList<Integer> output = new LinkedList(); if(root==null){ return output; } Stack s = new Stack(); TreeNode node; s.push(root); while(!s.empty()){ //注意记忆循环条件 node = (TreeNode)s.pop(); output.addFirst(node.val); if(node.left!=null){

数据结构与算法之二叉树

馋奶兔 提交于 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;

二叉树遍历

心已入冬 提交于 2019-12-01 02:39:53
public class BinaryTree { public static void main(String[] args) { Node root = new Node(1); root.left = new Node(2); root.right = new Node(3); root.left.left = new Node(4); root.left.right = new Node(5); root.right.left = new Node(6); root.right.right = new Node(7); print(root); } /** * 先序遍历:访问根结点的操作发生在遍历其左右子树之前。 根节点 -> 左子树 -> 右子树 1 2 4 5 3 6 7 * 中序遍历:访问根结点的操作发生在遍历其左右子树中间。 左子树 -> 根节点 -> 右子树 4 2 5 1 6 3 7 * 后序遍历:访问根结点的操作发生在遍历其左右子树之后。 左子树 -> 右子树 -> 根节点 4 5 2 6 7 3 1 * */ public static void print(Node root) { if (root == null) { return; } // 先序遍历,这行是第一次来到该节点 // System.out.print(root.value + " ");

NOIp初赛题目整理

寵の児 提交于 2019-12-01 00:21:50
NOIp初赛题目整理 这个 blog 用来整理扶苏准备第一轮 csp 时所做的与 csp 没 有 关 系 的历年 noip-J/S 初赛题目,记录了一些我从不知道的细碎知识点,还有一些憨憨题目,不定期更新。 1、(07senior,5) 在C 语言中,表达式 \(23~\mid~2~\land^~5\) 的值是( ) ​ A. \(23\) B. \(1\) C. \(18\) D. \(32\) E. \(24\) Answer:A Solution:这题一看就是要考运算符优先级来着。在 \(C\) 语言中, 按位与大于按位异或大于按位或 ,这里的大于指优先级大于,优先级越大越优先计算,因此计算过程为 \(2~\land~5~=~7\) 。然后计算 \(23~\mid~7 = 23\) 。 需要指出的是,左右移的优先级大于上述三个运算,因此 \(C\) 语言表达式 1 | p << 1 是先算 p << 1 ,再对 \(1\) 取或,例如 \(1~\mid~3~<<~1\) 的答案是 \(9\) 。 2、(07senior,12) 与十进制数 \(17.5625\) 对应的 \(8\) 进制数是( )。 ​ A. \(21.5625\) B. \(21.44\) C. \(21.73\) \(D.21.731\) Answer:B Solution:这里介绍一下分数的进制转换

图解数据结构-树及树的遍历

末鹿安然 提交于 2019-11-30 14:58:14
当你第一次学习编码时,大部分人都是将数组作为主要数据结构来学习。 之后,你将会学习到哈希表。如果你是计算机专业的,你肯定需要选修一门数据结构的课程。上课时,你又会学习到链表,队列和栈等数据结构。这些都被统称为线性的数据结构,因为它们在逻辑上都有起点和终点。 当你开始学习树和图的数据结构时,你会觉得它是如此的混乱。因为它的存储方式不是线性的,它们都有自己特定的方式存储数据。 定义 树是众所周知的非线性数据结构。它们不以线性方式存储数据。他们按层次组织数据。 树的定义 树(Tree)是n(n>=0)个结点的有限集。n=0时称为空树。 在任意一颗非空树中: (1) 有且仅有一个 特定的称为根(Root)的结点。 (2)当n>1时,其余结点可分为m(m>0)个 互不相交的有限集 T1、T2、.....、Tm,其中每一个集合本身又是一棵树,并且称为根的子树(SubTree)。 下图就符合树的定义: 其中根结点A有两个子树: 我们硬盘的文件系统就是很经典的树形结构。 “树”它具有以下的特点: ①每个节点有零个或多个子节点; ②没有父节点的节点称为根节点; ③每一个非根节点有且只有一个父节点; ④除了根节点外,每个子节点可以分为多个不相交的子树; 树( tree )是被称为结点( node )的实体的集合。结点通过边( edge )连接。每个结点都包含值或数据( value/date )

二叉树先序、中序、后续遍历非递归

心不动则不痛 提交于 2019-11-30 13:20:01
1 ** 2 * 二叉树先序遍历非递归 3 * @param root 4 */ 5 public void preOrder_no_recursive(TreeNode root){ 6 if(root == null) return; 7 8 Stack<TreeNode> stack = new Stack<>(); 9 stack.add(root); 10 while(!stack.isEmpty()){ 11 TreeNode tn = stack.pop(); 12 System.out.println(tn.val); // 输出 13 if(tn.right != null) stack.add(tn.right); 14 if(tn.left != null)stack.add(tn.left); 15 } 16 } 17 18 /** 19 * 二叉树中序遍历非递归 20 * @param root 21 */ 22 public void inOrder_no_recursive(TreeNode root){ 23 if(root==null)return; 24 Stack<TreeNode> stk = new Stack<TreeNode>(); 25 TreeNode p = root;//辅助节点 26 stk.add(p); 27 while

二叉树的遍历算法

大城市里の小女人 提交于 2019-11-30 12:05:43
遍历(Traverse) 就是按照某种次序访问树中的所有结点,且每个结点恰好访问一次 也就是说,按照被访问的次序,可以得到由树中所有结点排成的一个序列 树的遍历也可以看成是人为的将非线性结构线性化 这里的“访问”是广义的,可以是对结点作各种处理,例如输出结点信息、更新结点信息等 在我们的现实中,并不真正的“访问”这些结点,而是得到一个结点的线性序列,以线性表的形式输出 将整个二叉树看做三部分:根、左子树、右子树。如果规定先遍历左子树、在遍历右子树,那么根据根的遍历顺序就有三种遍历方式: 左子树 右子树 根 先序/根遍历DLR:根 左子树 右子树 中序/根遍历LDR:左子树 根 右子树 后序/根遍历LRD:左子树 右子树 根 注意:由于树的递归定义,其实对三种遍历的概念其实也是一个递归的描述过程 先序/根遍历DLR:1 4 5 2 3 6 7 中序/根遍历LDR:4 5 1 3 2 6 7 后序/根遍历LRD:5 4 3 7 6 2 1 如果按层次遍历,没有递归 面试题:已知一棵二叉树的后序遍历的序列为5 4 3 7 6 2 1,中序遍历的序列为4 5 1 3 2 6 7,则其先序遍历的序列是什么? 只要给定中序遍历,先序遍历或者后序遍历再给一个,就可以求出另一个 后序遍历最后肯定是根,所以确定1是根 所以4 5是左子树,3 2 6 7是右子树 依此类推 /** *二叉链表的结点 *

二叉树遍历问题、时间空间复杂度、淘汰策略算法、lru数据结构、动态规划贪心算法

我与影子孤独终老i 提交于 2019-11-30 09:19:58
二叉树的前序遍历、中序遍历、后序遍历 前序遍历 遍历顺序规则为【根左右】 ABCDEFGHK 中序遍历 遍历顺序规则为【左根右】 BDCAEHGKF 后序遍历 遍历顺序规则为【左右根】 DCBHKGFEA 什么是时间复杂度和空间复杂度 时间复杂度 是指执行当前算法所消耗的时间 空间复杂度 是指执行当前算法需要占用多少内存空间 评价一个算法的效率主要是看它的时间复杂度和空间复杂度。然后有时候鱼和熊掌不可得兼,所以我们就需要从中去取一个平衡点 知道淘汰策略的哪些算法? lru算法如果让你实现你会选择哪种数据结构 LRU算法的原理(least recently used,最近最少使用): LRU的四种实现方式 LRU-K 原理:LRU-K中的K代表最近使用的次数,因此LRU可以认为是LRU-1。LRU-K的主要目的是为了解决LRU算法“缓存污染”的问题,其核心思想是将“最近使用过1次”的判断标准扩展为最近使用过K次 实现:相比于LRU,LRU-K需要多维护一个队列,用于记录所有缓存数据被访问的历史。只有当数据的访问次数达到K次的时候,才会将数据放入到缓存中。当需要淘汰数据的时候,LRU-K后淘汰第K次访问时间据当前时间最大的数据。 过程 数据第一次被访问,加入到访问历史列表 如果数据在访问历史列表里后没有达到K次访问,就按照一定的规则(FIFO,LRU)淘汰