遍历

邻接表(数组实现)

假装没事ソ 提交于 2020-02-25 05:11:11
之前我们介绍过图的邻接矩阵存储法,它的空间和时间复杂度都是N2,现在我来介绍另外一种存储图的方法:邻接表,这样空间和时间复杂度就都是M。对于稀疏图来说,M要远远小于N2。先上数据,如下。 4 5 1 4 9 4 3 8 1 2 5 2 4 6 1 3 7 第一行两个整数n m。n表示顶点个数(顶点编号为1~n),m表示边的条数。接下来m行表示,每行有3个数x y z,表示顶点x到顶点y的边的权值为z。下图就是一种使用链表来实现邻接表的方法。 上面这种实现方法为图中的每一个顶点(左边部分)都建立了一个单链表(右边部分)。这样我们就可以通过遍历每个顶点的链表,从而得到该顶点所有的边了。使用链表来实现邻接表对于痛恨指针的的朋友来说,这简直就是噩梦。这里我将为大家介绍另一种使用数组来实现的邻接表,这是一种在实际应用中非常容易实现的方法。这种方法为每个顶点i(i从1~n)也都保存了一个类似“链表”的东西,里面保存的是从顶点i出发的所有的边,具体如下。 首先我们按照读入的顺序为每一条边进行编号(1~m)。比如第一条边“1 4 9”的编号就是1,“1 3 7”这条边的编号是5。 这里用u、v和w三个数组用来记录每条边的具体信息,即u[i]、v[i]和w[i]表示第i条边是从第u[i]号顶点到v[i]号顶点(u[i]àv[i]),且权值为w[i]。

巧妙的邻接表(数组实现)

别等时光非礼了梦想. 提交于 2020-02-25 05:08:55
之前我们介绍过图的邻接矩阵存储法,它的空间和时间复杂度都是N2,现在我来介绍另外一种存储图的方法:邻接表,这样空间和时间复杂度就都是M。对于稀疏图来说,M要远远小于N2。先上数据,如下。 4 51 4 94 3 81 2 52 4 61 3 7 第一行两个整数n m。n表示顶点个数(顶点编号为1~n),m表示边的条数。接下来m行表示,每行有3个数x y z,表示顶点x到顶点y的边的权值为z。下图就是一种使用链表来实现邻接表的方法。 上面这种实现方法为图中的每一个顶点(左边部分)都建立了一个单链表(右边部分)。这样我们就可以通过遍历每个顶点的链表,从而得到该顶点所有的边了。使用链表来实现邻接表对于痛恨指针的的朋友来说,这简直就是噩梦。这里我将为大家介绍另一种使用数组来实现的邻接表,这是一种在实际应用中非常容易实现的方法。这种方法为每个顶点i(i从1~n)也都保存了一个类似“链表”的东西,里面保存的是从顶点i出发的所有的边,具体如下。 首先我们按照读入的顺序为每一条边进行编号(1~m)。比如第一条边“1 4 9”的编号就是1,“1 3 7”这条边的编号是5。 这里用u、v和w三个数组用来记录每条边的具体信息,即u[i]、v[i]和w[i]表示第i条边是从第u[i]号顶点到v[i]号顶点(u[i]àv[i]),且权值为w[i]。 再用一个first数组来存储每个顶点其中一条边的编号

力扣739——每日温度

萝らか妹 提交于 2020-02-24 15:54:08
这道题主要是找规律,优化的时候可以利用数据结构的特性(数组和栈)。 原题 根据每日 气温 列表,请重新生成一个列表,对应位置的输入是你需要再等待多久,温度才会升高超过该日的天数。如果之后都不会升高,请在该位置用 0 来代替。 例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。 提示:气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数。 原题url:https://leetcode-cn.com/problems/daily-temperatures/ 解题 优先队列 如果正向思考的话,就是从前向后遍历,将温度存储在一个优先级队列中(小顶堆),队列中的结构需要记录温度和天数。 遍历时需要找到队列中最小的值是否大于当前温度,如果大于,则更新结果;如果小于,则将当前记录放入队列中。 接下来看看代码: class Solution { public int[] dailyTemperatures(int[] T) { // 以温度为排序依据的小顶堆,温度越低越靠前 PriorityQueue<Node> queue = new PriorityQueue<>(Comparator

数据结构与算法分析:(三)链表(上)

让人想犯罪 __ 提交于 2020-02-24 13:54:32
一、什么是链表? 链表是一种物理上 非连续 、 非顺序 的存储结构,数据元素之间的顺序是通过每个元素的 指针 (类似C语言中的指针,Java中是引用)关联的。 链表由一系列节点组成,每个节点一般至少会包含两部分信息:一部分是元素数据本身,另一部分是指向下一个元素地址的“指针”。这样的存储结构让链表相比其他线性的数据结构来说,操作会复杂一些。 说到链表,我们经常拿来与数组比。我们先看下面一张图再来对比它们的各自的优劣。 从图中我们看到,数组需要一块 连续 的内存空间来存储,对内存的要求比较高。如果我们申请一个 100MB 大小的数组,当内存中没有连续的、足够大的存储空间时,即便内存的剩余总可用空间大于 100MB,仍然会申请失败。 而链表恰恰相反,它并不需要一块连续的内存空间,它通过“指针”将一组零散的内存块串联起来使用,所以如果我们申请的是 100MB 大小的链表,根本不会有问题。 这里先思考一下下面这个问题。 Q:数组在实现上为什么使用的是连续的内存空间? A:可以借助 CPU 的缓存机制,预读数组中的数据,所以访问效率更高。而链表在内存中并不是连续存储,所以对 CPU 缓存不友好,没办法有效预读。 Q:上一答案中CPU缓存机制指的是什么?为什么就数组更好了? A: CPU在从内存读取数据的时候,会先把读取到的数据加载到CPU的缓存中

Iterator迭代器

…衆ロ難τιáo~ 提交于 2020-02-24 04:57:58
1 Iterator接口 在程序开发中,经常需要遍历集合中的所有元素。针对这种需求,JDK专门提供了一个接口 java.util.Iterator 。 Iterator 接口也是Java集合中的一员,但它与 Collection 、 Map 接口有所不同, Collection 接口与 Map 接口主要用于存储元素,而 Iterator 主要用于迭代访问(即遍历) Collection 中的元素,因此 Iterator 对象也被称为迭代器。 想要遍历Collection集合,那么就要获取该集合迭代器完成迭代操作,下面介绍一下获取迭代器的方法: public Iterator iterator() : 获取集合对应的迭代器,用来遍历集合中的元素的。 下面介绍一下迭代的概念: 迭代 :即Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。 Iterator接口的常用方法如下: public E next() :返回迭代的下一个元素。 public boolean hasNext() :如果仍有元素可以迭代,则返回 true。 接下来我们通过案例学习如何使用Iterator迭代集合中元素: public class

Java 学习 #6

余生颓废 提交于 2020-02-23 23:04:10
Set集合的特点和应用 特点: 不可重复、无序 应用: Set< T > set = new HashSet<>(); 结论: Set集合保证元素的唯一性依赖:equals()和hashCode()两个方法 package cn . itcast . demo8 ; import java . util . HashSet ; import java . util . Iterator ; import java . util . Set ; public class Test { public static void main ( String [ ] args ) { //1.创建集合对象 Set < Student > set = new HashSet < > ( ) ; //2.创建元素对象 Student s1 = new Student ( "Q" , 41 ) ; Student s2 = new Student ( "W" , 31 ) ; Student s3 = new Student ( "E" , 21 ) ; Student s4 = new Student ( "E" , 21 ) ; Student s5 = new Student ( "Q" , 41 ) ; //3.将集合对象添加到元素对象中 set . add ( s1 ) ; set .

爬虫学习(二)---bs4库的使用

痞子三分冷 提交于 2020-02-23 22:52:37
文章目录 1. bs4库的安装 2. bs4的初始化 3. BeautifulSoup类的基本元素 4. bs4标签树的下行遍历 5.bs4标签树的上行遍历 6.bs4标签树的平行遍历 1. bs4库的安装 通过cmd安装 bs4 pip install beautifulsoup4 2. bs4的初始化 调用prettify()函数美化输出HTML源代码 import requests from bs4 import BeautifulSoup r = requests . get ( "http://www.baidu.com" ) soup = BeautifulSoup ( r . text , "html.parser" ) # 对html内容解析 print ( soup . prettify ( ) ) # 美化输出 BeautifulSoup(参数1:源代码, 参数二: 解析器) 解析器 来源 特点 html.parser bs4库 1、Python的内置标准库 2、执行速度适中 3、文档容错能力强 lxml pip install lxml 1、速度快 2、文档容错能力强 xml pip install lxml 1、速度快 2、唯一支持XML的解析器 html5lib pip install html5lib 1、最好的容错性 2、以浏览器的方式解析文档 3

js视角的数据结构和算法(三)

倖福魔咒の 提交于 2020-02-23 18:22:36
js视角的数据结构和算法(三) 栈 队列 栈和队列的应用 树 二叉树 二叉树的实现 二叉搜索树/二叉查找树/二叉排序树 二叉树的遍历 栈 栈是逻辑结构中线性结构中的一种,遵循先入后出的原则。 最先入栈的元素称为栈底元素,最后入栈的元素称为栈顶元素。 栈属于逻辑结构,需要依托物理结构而存在。通过数组和链表,都可以实现一个栈。 栈基本操作是入栈和出栈,只从某一侧进行入或出,不论是链表实现还是数组实现,时间复杂度都是O(1)。 //入栈 var arr = [ 1 , 2 , 3 , 4 ] arr . push ( 5 ) //出栈 var arr = [ 1 , 2 , 3 , 4 ] arr . pop ( ) 队列 队列也是逻辑结构中线性结构中的一种,遵循先入先出的原则。 队列就像排队一样,有队头(出口)和队尾(入口)。 队列基本操作是入队和出队,只从某一侧进行入或出,不论是链表实现还是数组实现,时间复杂度都是O(1)。 //入队 var arr = [ 1 , 2 , 3 , 4 ] arr . push ( 5 ) //出队 var arr = [ 1 , 2 , 3 , 4 ] arr . shift ( ) 栈和队列的应用 先入后出的栈和先入先出的队列在特点上决定了它们的不同应用场景。 栈可用于历史数据的获取,是一种回溯,也能用于将递归操作转换成基于栈的非递归。

数据结构 之 二叉排序树

和自甴很熟 提交于 2020-02-23 16:23:27
1、什么是二叉排序树 二叉排序树 又叫(排序树 搜索数)他是一个一棵空树,或者是一棵具有如下性质的树: 1)若左子树不为空,那么左子树上面的所有节点的关键字值都比根节点的关键字值小 2)若右子树不为空,那么右子树上面的所有节点的关键字值都比根节点的关键字值大 3)左右子树都为二叉树 4)没有重复值(这一点在实际中可以忽略) 2、如何遍历 二叉树中序遍历,先访问左节点,然后访问中间节点,然后在访问右节点 如上图 中序遍历一个树, 1、先访问根节点的左子树 12 ,它有左子树? 有 --> 结果: 2、访问 12 的左子树 9 ,它有左子树? 没有 --> 结果:9 3、它有右子树? 没有,访问上一级 --> 结果:9 12 4、12 是否有右子树 ? 有 , 访问 40 --》 结果: 9 12 5、 40是否有左子树? 有, 访问 35 ,且35 没有左子树 --> 结果: 9 12 35 6、 检查35 是否有右子树? 没有 , 访问它的根节点 --》 结果: 9 12 35 40 7、检查 40 是否有右子树? 有,访问 190 ,它有左子树 8、访问它的左子树 146, 检查它有左子树? 没有 —》 结果: 9 12 35 40 146 9、检查它有右子树? 无 , 访问它的父节点 190 --》 结果 : 9 12 35 40 146 190 10、 检查190

数据结构与算法之图(上)

懵懂的女人 提交于 2020-02-23 04:05:13
什么是图 图是一种非常强大的数据结构,图是由顶点的有穷非空集合和顶点之间边的集合组成,通 常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合。 当我们需要处理多对多这么一种关系时,我们就可以建立一张图来解决。图中的顶点是我 们的数据元素(线性表中我们把数据元素叫元素,树中叫结点,在图中数据元素我们则称 之为顶点),边就是这些研究对象之间的关系,通常称之为权重,具体应用中会有不同。 怎么存储图 邻接矩阵 用一个二维数组存放节点,节点之间有边的就把对应的数组元素赋值位1,代表存在。 邻接矩阵的好处就是能够直观的看到那些边之间存在关系,便于查询(只要输入你要查询 的两个顶点值便可以确定他在这个二维数组当中的位置),计算每一个顶点的入度或出度 时只需遍历一遍即可。 代码实现邻接矩阵构建图: 但我们不难发现这个二维数组沿红线分开的两部分是完全对称的,且红线上的值都为0(自 己到自己肯定是没有边的啦),精打细算的我们就会想能不能那一半不用可以节省点空间 啊! 于是我们有了上面这个解决方案,他优化了邻接矩阵的空间复杂度,但他也制造了一些不 便,变成一个一维数组来存储之后,查询是否存在边变得没那么容易,如果我们要查询点 V i 与V j 之间有没有边就要查询a[i*(i+1)/2+j]了。但无论怎样还是节省了空间。