遍历

根据先序遍历和中序遍历建立二叉树

匿名 (未验证) 提交于 2019-12-03 00:14:01
˼· 先序遍历服从规则 “根左右” ,所以由此可知,对于一个先序遍历得到的数组,第一个元素一定是 根节点 ; 中序遍历服从规则 ”左根右“ ,所以由此可知,对于一个中序遍历得到的数组,根节点左边的元素都属于根节点的 左子树 ,而根节点右边的元素都属于根节点的 右子树 ; 所以,我们可以先通过先序遍历的第一个元素确定根节点,然后通过中序遍历结合根节点,获得当前根节点的左右子树,再将子树看成一棵独立的树,继续使用先序遍历判断根节点,中序遍历判断子树的方式,最终建立起整棵树; 假设有一棵二叉树,先序遍历为 {1,2,4,7,3,5,6,8} ,中序遍历为 {4,7,2,1,5,3,8,6} ,则建树过程如下: 首先,通过先序遍历可知树的根节点为 1 ,则在中序遍历中,1左边的元素 4,7,2 即为根的左子树的元素,而 1 右边的元素 5,3,8,6 即为根节点的右子树; 对于左子树 4,7,2 来说,在先序遍历中,这三个点的顺序为 2,4,7 ,则 2 为根节点,而在中序遍历中, 4,7 均在 2 的左边,则 4,7 均为以 2 为根树的左子树,且没有右子树; 对于 4,7 这两个节点来说,先序遍历中, 4 节点在7节点之前,所以 4 为根节点,而 7 作为子树,在中序遍历中, 7 在 4 之后,所以 7 为右子树; 对于根节点 1 的右子树 5,3,8,6 来说,在先序遍历中, 3

数据结构总结

匿名 (未验证) 提交于 2019-12-03 00:13:02
一:概述: 数据结构: 是计算机存储和组织数据的方式,是相互间存在着一种或多种关系的数据元素的集合和该集合中 数据元素的关系。记作: Data_Structure(D,R) D: 是数据元素的集合 R: 是该集合中所有元素之间的关系的有限集合。 二:数据结构的研究对象 (一) 数据的逻辑结构: 反应数据元素之间的前后件关系,与计算机的存储位置无关。 1) 集合: 数据结构中的元素之间除了"同属一个集合”的相互关系外,别无其余关系。 2) 线性结构: 数据结构中的元素存在 一对一 的关系。 3) 树形结构: 数据结构中的元素存在 一对多 的关系。 4) 图结构: 数据结构中的元素存在 多对多 的关系。 (二) 数据的物理结构: 是指数据在计算机存储空间的存放形式,一种逻辑结构可以表示成多种存储结构。 (三)数据结构的运算: (1)Creat: 建立一个数据结构 (2)Destroy: 消除一个数据结构 (3)Delete: 从一个数据结构中删除一个数据元素 (4)Insert: 把一个数据元素插入到一个数据结构中 (5)Access: 对一个数据结构进行访问 (6)Modify: 对一个数据结构中的数据元素进行修改 (7)Sort: 对一个数据元素中的数据元素进行排序 (8)Search: 对一个数据元素中数据元素进行查找 三:线性表:a[ 0 ... n] 构成的一个表,长度为 n

树-基本概念,遍历,表示法

匿名 (未验证) 提交于 2019-12-03 00:13:02
树的基本概念和常用术语 节点的度:一个结点的儿子结点个数称为该节点的度 树的度:一棵树的度是指该树中结点的最大度数。如上图的树的度是3 叶节点或终端节点:度为零的节点。如上图中E,I,J,C,G,H是叶节点 非终端节点或分支节点:度不为零的节点。除根节点外的分支节点都叫做内部节点。 路径:若存在树中的一个节点序列k1,k2,…,kj,使得结点ki是ki+1的父结点(1<=i<j),则称该结点序列是树中从结点k1到结点kj的一条路径。 路径长度:路径所经过的边的数目。 节点高度:从该结点到各叶结点的最长路径长度,例如上图中B,C,D的高度分别是2,0,1 树的高度: (这里规定单根的高度为0) 根结点的高度 结点的深度(或层数):从树根到任一结点n有唯一的路径,称该路径的长度为结点n的深度(或层数)。从根结点算起,根为第0层,它的孩子为第1层…… 森林:m(m>=0)棵互不相交的树的集合 树的遍历 前序遍历:先访问树根n,然后依次前序遍历T1,T2,…,Tk。 中序遍历:先中序遍历T1,然后访问树根n,接着依次对T2,T3,…,Tk 进行中序遍历。 后序遍历:先依次对T1,T2,…,Tk进行后序遍历,最后访问树根n。 树的表示方法 父节点数组表示法 (1)树中的结点数字化为它们的编号1,2,…,n。 (2)用一个一维数组存储每个结点的父结点。即:father[k

ES5新增数组的方法

我们两清 提交于 2019-12-03 00:11:54
ES5新增数组的方法 ES5新增数组常见方法(indexOf/forEach/map/filter/some/every) .indexOf( data , start)   检测数组中是否存在指定数据,存在返回索引,不存在返回-1,start表示从第几位开始查询。 demo: var arr = ["a","45",67,true,"hello",67,45,25,13,89]; console.log(arr.indexOf(67)); // 2 console.log(arr.indexOf("world")); // -1 console.log(arr.indexOf("a")); // 0 console.log(arr.indexOf(67,3)); // 5 console.log(arr.indexOf(67,6)); // -1 .forEach( function(val,idx,self){ } ); 循环,遍历数组   数组的专属遍历方法,1个参数:回调函数,在回调函数身上又有三个参数 var f = arr.forEach(function(val,idx,self){ // console.log(val); // console.log(idx); }) console.log(f); // undefined .map( function(val

图的割点与割边(超详细!!!)

匿名 (未验证) 提交于 2019-12-03 00:11:01
・割点 割点概念,应该很好理解: 在一个无向图中,如果 删除某个顶点 ,这个图就不再连通(任意两点之间无法相互到达),那么这个顶点就是这个图的割点。 举个例子: 图中的 2号顶点 就是割点, 删除2号后,4,5不通,1,6也不通等等 如何求割点? 很容易想到的方法是:依次删除每一个顶点,然后用dfs或者bfs来检查图是否依然连通。 如果删除某个顶点后,导致图不再连通,那么刚才删除的顶点就是割点。 这种方法的时间复杂度是O(N(N+M))。 下面寻找 复杂度低 的方法来解决。 首先从图中任意节点开始dfs遍历上图,得到一颗生成树, 如下图,圆圈中数字是顶点编号, 圆圈右上角的数表示这个顶点在遍历时是第几个被访问到的,叫做“时间戳”。 在遍历的时候一定会遇到割点, 关键是如何认定一个顶点是割点呢??? 在深度优先遍历的时候访问到u( 点2 )点,此时图被u ( 点2 )分割成两部分,一部分为已访问点,另一部分为未访问点。如果u是割点,那剩下的未被访问点中至少有一个点在不经过点k的情况下无论如何也回不到已访问的点。 基本思路: 假如到了u后,图中还有顶点v是没有访问过的点,如何判断v在不经过u的情况下是否还能回到之前访问过的任意一个点?u是v的父亲,而之前访问过的顶点就是祖先。 也就是如何检测v在不经过父亲u的情 况下还能否回到祖先。那就是对v再 进行一次dfs,但此次遍历不经过u,

单链表代码实现和讲解

匿名 (未验证) 提交于 2019-12-03 00:09:02
1、链表的特性 链表分为单链表和多链表,链表相对于数组有什么好处? 不是按顺序存储,是链式存储,以节点的形式 每个节点都包含date域(节点的内容),next域(下一节点的位置) 链表可以没有头节点 链表按照节点的next来查找下一个节点,由此当查找时,必须从头开始找,查找麻烦;但是插入和删除时只需要改变前后节点的指定位置就可以,所以插入删除方便 2、代码讲解单链表的应用(代码实现)    //实体类 public class PersonNode { public int no ; public String name ; public PersonNode next ; public PersonNode ( int no , String name ) { this . no = no ; this . name = name ; } @Override public String toString () { return "PersonNode{" + "no=" + no + ", name='" + name + '\'' + '}' ; } } 添加节点    1 //添加操作 2 public void add ( PersonNode personNode ){ 3 //head节点不能动,需要一个节点进行辅助遍历 4 PersonNode temp = head

剑指offer2:C++实现的替换空格

匿名 (未验证) 提交于 2019-12-03 00:08:02
1. 题目描述 请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。 2. 思路和方法: 2.1 不建议的方法: 简单暴力解法 ,从头到尾遍历字符串,碰到空格,首先将后面的所有字符串往后移动2个字符,才能空出3个字符位子插入字符“%20”,对于一个长度为n的字符串,对每个空格,需要移动后面O(n)个字符,因此包含n个空格的字符串,总的时间复杂度为O(n*n)。 2.2 建议使用的方法: 中心思想 :统计字符串中空格的个数,计算扩容字符串后的长度,然后执行复制和替换。我们从后往前开始替换,首先遍历一遍字符串,统计出空格的个数,并由此能够计算出替换之后的字符串的长度。接着再次从后往前遍历字符串,同时设置两个指针P1和P2,P1指向原始字符串末尾,P2指向替换之后的字符串末尾。我们向前移动P1,逐个把它指向的字符复制到P2指向的位置,直到碰到第一个空格为止。然后把P1向前移动一格,在P2之前插入字符串“%20”,同时P2向前移动3格。重复此过程,直到所有的空格都已替换完。这种做法的时间复杂度为O(n)。 3. C++实现 #include <iostream> /* 将字符串中的空格替换成%20 */ class Solution { public : void replaceSpace

用for循环和用for-in循环遍历数组最大的区别

可紊 提交于 2019-12-03 00:06:48
用for循环和用for-in循环遍历数组最大的区别是啥: 最大的区别在与稀松数组:如果循环的数组是稀松数组的话用for循环会将中间的空下标(不论有没有都会从0到最后一个全都遍历一遍,没有属性名的直接为undefined ,而for-in循环会跳过这些没有的属性名) 来源: https://www.cnblogs.com/panghu123/p/11768471.html

js中对象遍历的几种方式

匿名 (未验证) 提交于 2019-12-03 00:05:01
// 对象的遍历方法 // 第一种 :通过for..in..的方式遍历对象 var obj ={ name : '小明' , age : 14 , job : '电竞' } for ( var k in obj ) { console . log ( k + '===' + obj [ k ]); //name===小明 age===14 job===电竞 } // 第二种:Object.keys(对象名) 访问对象的属性 Object.values(对象名) 访问对象的属性值 var obj1 = {     id : 12356 ,     name : '张三' ,     age : 19 } console . log ( Object . keys ( obj1 )) // ["id", "name", "age"] console . log ( Object . values ( obj1 )) //[12356, "张三", 19] // 第三种: 使用Object.getOwnPropertyNames(对象名) var obj2 = { id : 13579 , name : '李四' , age : 20 } Object . getOwnPropertyNames ( obj2 ). forEach ( function ( key ){ console

Spliterator&lt;T&gt; 接口

匿名 (未验证) 提交于 2019-12-03 00:05:01
文档说明 一个用于对一个源当中的元素进行遍历和分区的对象 一个 Spliterator 涵盖的源中的元素可以是数组、Collection、IO通道、生成器函数 一个 Spliterator 可以一个一个地遍历元素(tryAdvance()),也可以顺序地分块遍历(forEachRemaining()) 一个 Spliterator 可以对其元素使用 trySplit 进行分区形成另外的 Spliterator,使用在并行操作中 操作中使用的 Spliterator 但无法进行分割,或者分割结果高度不平衡或低效,则操作不能从并行当中获益 遍历以及分割都会消耗掉元素,每一个 Spliterator 只对其对应的单个块进行运算 一个 Spliterator 还会去报告一个装有其构造、源以及其元素的特性值的集合,特性值有:ORDERED、DISTINCT、SORTED、SIZED、NONNULL、IMMUTABLE、CONCURRENT、SUBSIZED 这些特性可被 Spliterator 的使用者调用,以特化或简化计算 特性值都是通过位操作进行标识的 部分特性值会额外地限定方法的行为 如:ORDER,遍历方法必须遵循它们在文档中定义好的顺序 未来可能还会定义新的特性值,因此实现者不应该给8个特性值以外的词赋予新的含义 当一个 Spliterator 不包含 `IMMUTABLE` 或