中序遍历

二叉树的遍历算法

大城市里の小女人 提交于 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)淘汰

C语言实现二叉树的基本功能

两盒软妹~` 提交于 2019-11-30 09:13:00
本程序实现二叉树的如下功能 1、以先序序列和中序序列构造二叉树 2、以层序序列和中序序列构造二叉树 3、先序遍历、中序遍历、后序遍历、层序遍历 4、求二叉树高度 5、验证这个二叉树是否具备这样的性质:任何一个子树中的结点集合,树根结点的值总是最小。(按字母序) 6、拷贝二叉树 7、将二叉树左右子树交换 8、销毁二叉树 9、删除值为x的节点及其全部子孙 binary_tree.h文件 注:queue.h文件在 这里 # ifndef __BINARY_TREE_H__ # define __BINARY_TREE_H__ # include <stdio.h> # include <stdlib.h> # include <string.h> # include <stdbool.h> # include "queue.h" # define SIZE_bt 1024 struct bt { char data ; struct bt * lchild , * rchild ; } ; struct bt * PreInBuild ( char * pre , char * in ) ; //以先序序列和中序序列构造二叉树 struct bt * LevelInBuild ( char * level , char * in ) ; //以层序序列和中序序列构造二叉树 void

数据结构及算法基础学习笔记

风格不统一 提交于 2019-11-30 06:01:56
1.python数据结构及算法基础学习笔记思维导图 2.程序代码演示 1.链表模型:linklist.py 1 """ 2 功能: 实现单链表的构建和操作 3 4 """ 5 6 # 创建节点类 7 class Node: 8 """ 9 思路 : *自定义类视为节点类,类中的属性为数据内容 10 *写一个next属性,用来和下一个 节点建立关系 11 """ 12 def __init__(self,val,next = None): 13 """ 14 val: 有用数据 15 next: 下一个节点引用 16 """ 17 self.val = val 18 self.next = next 19 20 21 # 链式线性表操作类 22 class LinkList: 23 """ 24 思路 : 生成单链表,通过实例化的对象就代表一个链表 25 可以调用具体的操作方法完成各种功能 26 """ 27 def __init__(self): 28 # 链表的初始化节点,没有有用数据,但是便于标记链表的开端 29 self.head = Node(None) 30 31 # 初始化链表,添加一组节点 32 def init_list(self,list_): 33 p = self.head # p 作为移动变量 34 for i in list_: 35 #

学习笔记之二叉树的遍历

空扰寡人 提交于 2019-11-30 05:47:19
分层遍历 将每一层的节点遍历出来,利用 LinkedList ,先压入根节点,循环遍历,循环的同时再将左节点,右节点分别加到尾部. // 分层遍历 (TreeNode root) if ( root == null ) return ; LinkedList < TreeNode > nodes = new LinkedList < > ( ) ; TreeNode last = root ; TreeNode nLast = root ; nodes . push ( root ) ; while ( ! nodeStack . isEmpty ( ) ) { TreeNode node = nodes . pop ( ) ; System . out . print ( node . data + " " ) ; if ( node . left != null ) { nodes . add ( node . left ) ; nLast = node . left ; } if ( node . right != null ) { nodes . add ( node . right ) ; nLast = node . right ; } if ( node == last ) { System . out . println ( " " ) ; last = nLast

高级PHP面试总结

故事扮演 提交于 2019-11-30 02:41:47
1、给你四个坐标点,判断它们能不能组成一个矩形,如判断([0,0],[0,1],[1,1],[1,0])能组成一个矩形。 勾股定理,矩形是对角线相等的四边形。只要任意三点不在一条直线上,任选一点,求这一点到另外三点的长度的平方,两个短的之和如果等于最长的,那么这就是矩形。 2、写一段代码判断单向链表中有没有形成环,如果形成环,请找出环的入口处,即P点 /* *单链表的结点类 */ class LNode{ //为了简化访问单链表,结点中的数据项的访问权限都设为public public int data; public LNode next; } class LinkListUtli { //当单链表中没有环时返回null,有环时返回环的入口结点 public static LNode searchEntranceNode(LNode L) { LNode slow=L;//p表示从头结点开始每次往后走一步的指针 LNode fast=L;//q表示从头结点开始每次往后走两步的指针 while(fast !=null && fast.next !=null) { if(slow==fast) break;//p与q相等,单链表有环 slow=slow.next; fast=fast.next.next; } if(fast==null || fast.next==null)

二叉搜索树的后序遍历判断

帅比萌擦擦* 提交于 2019-11-30 01:49:31
题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。 之前对于二叉搜索树,只知道中序遍历是递增的,今天做到这道题目,要求判断数组是不是二叉搜索树后序遍历的结果,一开始有点懵,后来在纸上画画,感觉很像递归的感觉,有一种特别像归并排序的那种感觉一样,然后发现对于每一个树的子结构而言,我们将其分成左右子树两部分就可以很明白这种递归的结构了,分成两部分,然后分别对左右在递归,直到叶子节点 1 public class Solution { 2 public boolean VerifySquenceOfBST(int [] sequence) { 3 if(sequence.length==0) 4 return false; 5 return helper(sequence,0,sequence.length-1); 6 } 7 public boolean helper(int[] arr, int l,int r) 8 { 9 if(l>=r) 10 return true; 11 for(int i=l;i<r;i++) 12 { 13 if(arr[i]>arr[r]) 14 { 15 for(int j=i;j<r;j++) 16 if(arr[j]<arr[r]) 17

javascript实现二叉搜索树

≡放荡痞女 提交于 2019-11-30 01:38:36
在使用javascript实现基本的数据结构中,练习了好几周,对基本的数据结构如 栈、队列、链表、集合、哈希表、树、图等内容进行了总结并且写了笔记和代码。 在 github中可以看到 点击查看 ,可以关注一下我哈。 树的基本术语 二叉树节点的存储结构 创建一个二叉搜索树 二叉树的先序、中序、后续遍历算法 二叉树的非递归先序、中序、后续遍历算法 。 文章对树了解的不多的人有点不友好,这里简单介绍(从书上抄下来)那些基本的一点概念吧。 看下面这个示意图 树的基本术语: 结点: A、B、C等都是结点,结点不仅包含数据元素,而且包含指向子树的分支。例如,A结点不仅包含数据元素A、还包含3个指向子树的指针。 结点的度: 结点拥有的子树个数或者分支的个数,例如A结点有3棵子树,所以A结点的度为3. 树的度: 树中各结点度的最大值。如例子中结点度最大为3(A、D结点)。最小为0(F、G、I、J、K、L、M),所以树的度为3。 叶子节点 :又叫做 终端节点, 指度为0的节点,F、G、I、J、K、L、M节点都是叶子节点。 孩子: 结点的子树的根,如A节点的孩子为B、C、D。 双亲: 与孩子的定义对应,如B C D结点的双亲都是A。 兄弟: 同一个双亲的孩子之间互为兄弟。如B、C、D互为兄弟,因为它们都是A节点的孩子。 祖先 :从根到某节点的路径上的所有结点,都是这个节点的祖先。如K的祖先是A B E

二叉树遍历实现及效率分析

主宰稳场 提交于 2019-11-30 01:07:33
1 理论 1、二叉树遍历方法 先序遍历遍历顺序:根–左--右 中序遍历遍历顺序:左–根--右 后序遍历遍历顺序:左–右--根 层序遍历遍历顺序:从上到下,从左到右 2、二叉树复原 已知 先序遍历序列 和 中序遍历序列 ,可以唯一确定一颗二叉树 已知 中序遍历序列 和 后序遍历序列 ,可以唯一确定一颗二叉树 已知 先序遍历序列 和 后序遍历序列 , 不 能唯一确定一颗二叉树 3、二叉树存储 顺序存储:用一维数组存储二叉树中的节点,并且节点的存储位置,也就是数组的下标要能体现节点之间的逻辑关系,一般只用于完全二叉树 。 链式存储:每个节点的结构具有一个存储数据的变量与两个指向孩子的指针域。 2 代码 #include <iostream> #include <vector> #include <stack> #include <queue> #include <ctime> using namespace std; struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; #pragma region 先序遍历 void preorderRecursion(TreeNode* node) { if (node) {

二叉树遍历

孤街浪徒 提交于 2019-11-29 23:51:32
前序遍历:根->左->右 中序遍历:左->根->右 后序遍历:左->右->根 假设树节点的定义如下: struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; 递归版 //前序遍历 void preorderTraversalRecursion(TreeNode *node) { if(!node) return; cout << node->val << " ";//操作当前节点 preorderTraversalRecursion(node->left); preorderTraversalRecursion(node->right); } //中序遍历 void inorderTraversalRecursion(TreeNode *node) { if(!node) return; inorderTraversalRecursion(node->left); cout << node->val << " ";//操作当前节点 inorderTraversalRecursion(node->right); } //后序遍历 void postorderTraversalRecursion(TreeNode