n21v2存储块数据
㈠ 计算机网络(3)| 数据链路层
数据链路层属于计算机网络的低层。数据链路层使用的信道主要是两种类型:
(1)点对点信道 。即信道使用的是一对一点对点通信方式。
(2)广播信道 。这种信道使用的是一对多的光播通信方式,相对复杂。在广播信道上连接的主机很多,因此必须使用专用的共享信道协议来协调这些主机的数据发送。
首先我们应该了解一些有关点对点信道的一点基本概念。
(1)数据链路 。值得是当我们需要在一条线路上传送数据时,除了有一条物理线路外(链路),还必须有一些必要的通信协议来控制这些数据的传输,若把实现这些协议的硬件和软件加到链路上就构成了数据链路。
(2)帧 。帧指的是点对点信道的数据链路层的协议数据单元,即数据链路层把网络层交下来的数据构成帧发送到链路上以及把接收到的帧中的数据取出并上交给网络层。
点对点信道的数据链路层在进行通信时的主要步骤如下:
(1)结点A的数据链路层把网络层交下来的IP数据报添加首部和尾部封装成帧。
(2)结点A把封装好的帧发送给结点B的数据链路层。
(3)若B接收的帧无差错,则从接收的帧中提取出IP数据报上交给上面的网络层;否则丢弃这个帧。
接下来是来介绍数据链路层的三个基本问题,而这三个问题对于各种数据链路层的协议都是通用的。
(1)封装成帧 。指的是在一段数据的前后分别添加首部和尾部,这样就构成了一个帧,从而能够作为数据链路层的基本单位进行数据传输。在发送帧时,是从帧的首部开始发送的。各种数据链路层协议都对帧首部和帧尾部的格式有着明确的规定,且都规定了所能传送的 帧的数据部分 长度上限—— 最大传送单元MTU 。首部和尾部的作用是进行帧定界,帧定界可以使用特殊的 帧定界符 ,当数据在传输中出现差错时,通过帧的帧定界符就可以知道收到的数据是一个不完整的帧(即只有首部开始符而没有结束符)。
(2)透明传输 。从上面的介绍中知道帧的开始和结束标记使用了专门的控制字符,因此所传输的数据中任何与帧定界符相同的比特编码是不允许出现的,否则就会出现帧定界错误。当传送的帧是用文本文件组成的帧时,它的数据部分一定不会出现和帧定界符相同的字符,这样的传输就叫做 透明传输 。为了解决其他类型文件传输时产生的透明传输问题,就将帧定界符的前面插入一个 转义字符ESC ,这种方法称为 字节填充 。如果转义字符也出现在数据中,就在转义字符前面加上一个转义字符,当接收端收到两个转义字符时,就删除前面的那一个。
(3)差错检测 。在现实中,通信链路都不会是完美的,在传输比特的过程当中都是会产生差错的,1变成0或者0变成1都是可能发生的,我们把这样的错误叫做差错检测。在数据链路层中,为了保证数据传输的可靠性,减少差错出现的数量,就会采用各种差错检测措施,目前最常使用的检错技术是 循环冗余校验 。它的原理简单来说就是在被传输的数据M后面添加供错检测用的n为冗余码,构成一个帧数据发送出去。关于n位冗余码的得出方式与检验方式,可以 点击这里进一步了解 。
对于点对点链路,点对点协议PPP是目前使用得最广泛的数据链路层协议。由于因特网的用户通常都要连接到某个ISP才能接入到因特网,PPP协议就是用户计算机和ISP进行通信所使用的数据链路层协议。
在设计PPP协议时必须要考虑以下多方面的需求:
(1)简单 。简单的设计可使协议在实现时不容易出错,这样使得不同厂商对协议的不同实现的互操作性提高了。
(2)封装成帧 。PPP协议必须规定特殊的字符作为帧定界符(即标志一个帧的开始和结束的字符),以便使接收端从收到的比特流中能准确的找出帧的开始和结束的位置。
(3)透明性 。PPP协议必须保证数据传输的透明性。如果说是数据中碰巧出现和帧定界符一样的比特组合时,就要采用必要的措施来解决。
(4)多种网络层协议 。PPP协议必须能够在同一条物理链路上同时支持多种网络层协议(IP和IPX等)的运行。
(5)多种类型链路 。除了要支持多种网络层的协议外,PPP还必须能够在多种链路上运行(串行与并行链路)。
(6)差错检测 。PPP协议必须能够对接收端收到的帧进行检测,并舍弃有差错的帧。
(7)检测连接状态 。必须具有一种机制能够及时(不超过几分钟)自动检测出链路是否处于正常工作状态。
(8)最大传送单元 。协议对每一种类型的点对点链路设置最大传送单元MTU。
(9)网络层地址协商 。协议必须提供一种机制使通信的两个网络层(如两个IP层)的实体能够通过协商知道或能够配置彼此的网络层地址。
(10)数据压缩协商 。协议必须能够提供方法来协商使用数据压缩算法。但PPP协议不要求将数据压缩算法进行标准化。
PPP协议主要是由三个方面组成的:
(1) 一个将IP数据报封装到串行链路的方法。
(2) 一个用来建立、配置和测试数据链路连接的链路控制协议LCP(Link Control Protocol)。
(3) 一套网络控制协议NCP(Network Control Protocol),其中的每一个协议支持不同的网络层协议,如IP、OSI的网络层、DECnet,以及AppleTalk等。
最后来介绍PPP协议帧的格式:
首先是各个字段的意义。首部中的地址字段A规定为0xFF,控制字段C规定为0x03,这两个字段并没有携带PPP帧的信息。首部的第一个字段和尾部的第二个字段都是标识字段F(Flag)。首部的第四个字段是2字节的协议字段。当协议字段为0x0021时,PPP帧的信息部分字段就是IP数据报。若为0xC021,则信息字段是PPP链路控制协议LCP的数据,而 0x8021表示这是网络层的控制数据。尾部中的第一个字段(2字节)是使用CRC的帧检验序列FCS。
接着是关于PPP协议的差错检测的方法,主要分为字节填充和零比特填充。当是PPP异步传输时,采用的是字节填充的方法。字节填充是指当信息字段中出现和标志字段一样的比特(0x7E)组合时,就必须采取一些措施使这种形式上和标志字段一样的比特组合不出现在信息字段中。而当PPP协议使用的是同步传输时,就会采用零比特填充方法来实现透明传输,即只要发现有5个连续1,则立即填入一个0的方法。
广播信道可以进行一对多的通信。由于局域网采用的就是广播通信,因此下面有关广播通信的讨论就是基于局域网来进行的。
首先我们要知道局域网的主要 特点 ,即网络为一个单位所拥有,且地理范围和站点数目均有限。在局域网才出现时,局域网比广域网有着较高的数据率、较低的时延和较小的误码率。
局域网的 优点 主要有一下几个方面:
(1) 具有广播功能,从一个站点可方便地访问全网。
(2) 便于系统的扩展和逐渐地演变,各设备的位置可灵活地调整和改变。
(3) 提高了系统的可靠性(reliability)、可用性(availibility)、生存性(survivability)。
关于局域网的分类,我们一般是对局域网按照网络拓扑进行分类:
1.星状网: 由于集线器的出现和双绞线大量用于局域网中,星形以太网和多级星形结构的以太网获得了非常广泛的应用。
2.环形网: 顾名思义,就是将各个主机像环一样串起来的拓扑结构,最典型的就是令牌环形网。
3.总线网: 各站直接连在总线上。总线两端的匹配电阻吸收在总线上传播的电磁波信号的能量,避免在总线上产生有害的电磁波反射。
以太网主要有两个标准,即DIX Ethernet V2和IEEE 802.3标准,这两种标准的差别很小,可以不是很严格的区分它们。
但是由于有关厂商的商业上的激烈竞争,导致IEEE 802委员会未能形成一个最佳的局域网标准而制定了几个不同的局域网标准,所以为了数据链路层能够更好的适应各种不同的标准,委员会就把局域网的数据链路层拆成两个子层: 逻辑链路控制LLC子层 和 媒体接入控制MAC子层 。
计算机与外界局域网的连接是通过通信适配器(adapter)来进行的。适配器本来是在电脑主机箱内插入的一块网络接口板(或者是在笔记本电脑中插入一块PCMCIA卡),这种接口板又称为网络接口卡NIC(Network Interface Card)或简称为网卡。适配器和局域网之间的通信是通过电缆或双绞线以串行传输方式进行的,而适配器和计算机之间的通信则是通过计算机主板上的I/O总线以并行传输方式进行的,因此适配器的一个重要功能就是要进行数据串行传输和并行传输的转换。由于网络上的数据率和计算机总线上的数据率并不相同,所以在适配器中必须装有对数据进行缓存的存储芯片。若在主板上插入适配器时,还必须把管理该适配器的设备驱动程序安装在计算机的操作系统中。这个驱动程序以后就会告诉适配器,应当从存储器的什么位置上把多长的数据块发送到局域网,或应当在存储器的什么位置上把局域网传送过来的数据块存储下来。适配器还要能够实现以太网协议。
要注意的是,适配器在接收和发送各种帧时是不使用计算机的CPU的,所以这时计算机中的CPU可以处理其他的任务。当适配器收到有差错的帧时,就把这个帧丢弃而不必通知计算机,而当适配器收到正确的帧时,它就使用中断来通知该计算机并交付给协议栈中的网络层。当计算机要发送IP数据报时,就由协议栈把IP数据报向下交给适配器,组装成帧后发送到局域网。特别注意: 计算机的硬件地址—MAC地址,就在适配器的ROM中。计算机的软件地址—IP地址,就在计算机的存储器中。
CSMA/CD协议主要有以下3个要点:
1.多点接入 :指的是这是总线型网络,许多计算机以多点接入的方式连接在一根总线上。
2.载波监听 :就是用电子技术检测总线上有没有其他的计算机也在发送。载波监听也称为检测信道,也就是说,为了获得发送权,不管在发送前,还是在发送中,每一个站都必须不停的检测信道。如果检测出已经有其他站在发送,则自己就暂时不发送数据,等到信道空闲时才发送数据。而在发送中检测信道是为了及时发现有没有其他站的发送和本站发送的碰撞。
3.碰撞检测 :也就是边发送边监听。适配器一边发送数据一边检测信道上的信号电压的变化情况,以便判断自己在发送数据时其他站是否也在发送数据。所谓碰撞就是信号之间产生了冲突,这时总线上传输的信号严重失真,无法从中恢复出有用的信息来。
集线器的一些特点如下:
(1)使用集线器的以太网在逻辑上仍然是一个总线网,各个站点共享逻辑上的总线,使用的还是CSMA/CD协议。
(2)一个集线器是有多个接口。一个集线器就像一个多接口的转发器。
(3)集线器工作在物理层,所以它的每一个接口仅仅是简单的转发比特。它不会进行碰撞检测,所以当两个接口同时有信号的输入,那么所有的接口都将收不到正确的帧。
(4)集线器自身采用了专门的芯片来进行自适应串音回波抵消。这样可使接口转发出去的较强的信号不致对该接口收到的较弱信号产生干扰。
(5)集线器一般都有少量的容错能力和网络管理能力,也就是说如果在以太网中有一个适配器出现了故障,不停地发送以太网帧,这是集线器可以检测到这个问题从而断开与故障适配器的连线。
在局域网中,硬件地址又称为物理地址或者MAC地址,这种地址是用在MAC帧中的。由于6字节的地址字段可以使全世界所有的局域网适配器具有不同的地址,所以现在的局域网适配器都是使用6字节MAC地址。
主要负责分配地址字段的6个字节中的前3个字节。世界上凡事要生产局域适配器的厂家都必须向IEEE购买这3个字节构成的地址号,这个地址号我们通常叫做 公司标识符 ,而地址字段的后3个字节则由厂家自行指派,称为 扩展标识符 。
IEEE规定地址字段的第一字节的最低位为I/G位。当I/G位为0时,地址字段表示一个单个站地址,而当I/G位为1时表示组地址,用来进行多播。所以IEEE只分配地址字段前三个字节中的23位,当I/G位分别为0和1时,一个地址块可分别生 2^24 个单个站地址和2^24个组地址。IEEE还把地址字段第1个字节的最低第二位规定为G/L位。当G/L位为0时是全球管理,来保证在全球没有相同的地址,厂商向IEEE购买的都属于全球管理。当地址段G/L位为1时是本地管理,这时用户可以任意分配网络上的地址,但是以太网几乎不会理会这个G/L位的。
适配器对MAC帧是具有的过滤功能的,当适配器从网络上每收到一个MAC帧就先用硬件检查MAC帧中的目的地址。如果是发往本站的帧则收下,然后再进行其他的处理,否则就将此帧丢弃。这样做就可以不浪费主机的处理机和内存资源这里发往本站的帧包括以下三种帧:
(1)单播帧:即收到的帧的MAC地址与本站的硬件地址相同。
(2)广播帧:即发送给本局域网上所有站点的帧。
(3)多播帧:即发送给本局域网上一部分站点的帧。
常用的以太网MAC帧格式是以太网V2的MAC帧格式。如下图:
可以看到以太网V2的MAC帧比较的简单,有五个字段组成。前两个字段分别为6字节长的目的地址和源地址字段。第三个字段是2字节的类型字段,用来标志上一层使用的是什么协议,以便把收到的MAC帧的数据上交给上一层的这个协议。下一个字段是数据字段,其长度在46到1500字节之间。最后一个字段是4字节的帧检验序列FCS(使用CRC检验)。
从图中可以看出,采用以太网V2的MAC帧并没有一个结构来存储一个数据的帧长度。这是由于在曼彻斯特编码中每一个码元的正中间一定有一次电压的转换,如果当发送方在发送完一个MAC帧后就不再发送了,则发送方适配器的电压一定是不会在变化的。这样接收方就可以知道以太网帧结束的位置,在这个位置减去FCS序列的4个字节,就可以知道帧的长度了。
当数据字段的长度小于42字节时,MAC子层就会在MAC帧后面加入一个整数字节来填充字段,来保证以太网的MAC帧的长度不小于64字节。当MAC帧传送给上层协议后,上层协议必须具有能够识别填充字段的功能。当上层使用的是IP协议时,其首部就有一个总长度字段,因此总长度加上填充字段的长度,就是MAC帧的数据字段的长度。
从图中还可以看出,在传输MAC帧时传输媒体上实际是多发送了8个字节,这是因为当MAC帧开始接收时,由于适配器的时钟尚未与比特流达成同步,因此MAC帧的最开始的部分是无法接收的,结果就是会使整个MAC成为无用帧。所以为了接收端能够迅速的与比特流形成同步,就需要在前面插入这8个字节。这8个字节是由两个部分组成的,第一个部分是由前7个字节构成的前同步码,它的主要作用就是就是实现同步。第二个部分是帧开始界定符,它的作用就是告诉接收方MAC帧马上就要来了。需要注意的是,帧与帧之间的传输是需要一定的间隔的,否则接收端在收到了帧开始界定符后就会认为后面的都是MAC帧而会造成错误。
以太网上的主机之间的距离不能太远,否则主机发送的信号经过铜线的传输就会衰减到使CSMA/CD协议无法正常工作,所以在过去常常使用工作在物理层的转发器来拓展以太网的地理覆盖范围。但是现在随着双绞线以太网成为以太网的主流类型,拓展以太网的覆盖范围已经很少使用转发器,而是使用光纤和一对光纤调制解调器来拓展主机和集线器之间的距离。
光纤解调器的作用是进行电信号与光信号的转换。由于光纤带来的时延很小,并且带宽很宽,所以才用这种方法可以很容易地使主机和几公里外的集线器相连接。
如果是使用多个集线器,就可以连接成覆盖更大范围的多级星形结构的以太网:
使用多级星形结构的以太网不仅能够让连接在不同的以太网的计算机能够进行通信,还可以扩大以太网的地理覆盖范围。但是这样的多级结构也带来了一些缺点,首先这样的结构会增大它们的碰撞域,这样做会导致图中的某个系的两个站在通信时所传送的数据会通过所有的集线器进行转发,使得其他系的内部在这时都不能进行通信。其次如果不同的以太网采用的是不同的技术,那么就不可能用集线器将它们互相连接起来。
拓展以太网的更常用的方法是在数据链路层中进行的,在开始时人们使用的是网桥。但是现在人们更常用的是 以太网交换机 。
以太网交换机实质上是一个多接口的网桥,通常是有十几个或者更多的接口,而每一个接口都是直接与一个单台主机或者另一个以太网交换机相连。同时以太网交换机还具有并行性,即能同时连通多对接口,使多对主机能同时通信,对于相互通信的主机来说都是独占传输媒体且无碰撞的传输数据。
以太网交换机的接口还有存储器,能够在输出端口繁忙时把到来的帧进行缓存,等到接口不再繁忙时再将缓存的帧发送出去。
以太网交换机还是一种即插即用的设备,它的内部的地址表是通过自学习算法自动的建立起来的。以太网交换机由于使用了专用的交换结构芯片,用硬件转发,它的转发速率是要比使用软件转发的网桥快很多。
如下图中带有4个接口的以太网交换机,它的4个接口各连接一台计算机,其MAC地址分别为A、B、C、D。在开始时,以太网交换机里面的交换表是空的。
首先,A先向B发送一帧,从接口1进入到交换机。交换机收到帧后,先查找交换表,但是没有查到应从哪个接口转发这个帧,接着交换机把这个帧的源地址A和接口1写入交换表中,并向除接口1以外的所有接口广播这个帧。C和D因为目的地址不对会将这个帧丢弃,只有B才收下这个目的地址正确的帧。从新写入的交换表(A,1)可以得出,以后不管从哪一个接口收到帧,只要其目的地址是A,就应当把收到的帧从接口1转发出去。以此类推,只要主机A、B、C也向其他主机发送帧,以太网交换机中的交换表就会把转发到A或B或C应当经过的借口号写入到交换表中,这样交换表中的项目就齐全了,以后要转发给任何一台主机的帧,就都能够很快的在交换表中找到相应的转发接口。
考虑到有时可能要在交换机的接口更换主机或者主机要更换其网络适配器,这就需要更改交换表中的项目,所以交换表中每个项目都设有一定的有效时间。
但是这样的自学习有时也会在某个环路中无限制的兜圈子,如下图:
假设一开始主机A通过接口交换机#1向主机B发送一帧。交换机#1收到这个帧后就向所有其他接口进行广播发送。其中一个帧的走向:离开#1的3->交换机#2的接口1->接口2->交换机#1的接口4->接口3->交换机#2的接口1......一直循环下去,白白消耗网络资源。所以为了解决这样的问题,IEEE制定了一个生成树协议STP,其要点就是不改变网络的实际拓扑,但在逻辑上切断某些链路,从而防止出现环路。
虚拟局域网VLAN是由一些局域网网段构成的与物理位置无关的逻辑组,而这些网段具有某些共同的需求。每一个VLAN的帧都有一个明确的标识符,指明发送这个帧的计算机属于VLAN。要注意虚拟局域网其实只是局域网给用户提供的一种服务,而不是一种新型局域网。
现在已经有标准定义了以太网的帧格式的扩展,以便支持虚拟局域网。虚拟局域网协议允许在以太网的帧格式中插入一个4字节的标识符,称为VLAN标记,它是用来指明发送该帧的计算机属于哪一个虚拟局域网。VLAN标记字段的长度是4字节,插入在以太网MAC帧的源地址字段和类型字段之间。VLAN标记的前两个字节总是设置为0x8100,称为IEEE802.1Q标记类型。当数据链路层检测到MAC帧的源地址字段后面的两个字节的值是0x8100时,就知道现在插入了4字节的VLAN标记。于是就接着检查后面两个字节的内容,在后面的两个字节中,前3位是用户优先级字段,接着的一位是规范格式指示符CFI,最后的12位是该虚拟局域网VLAN标识符VID,它唯一的标志了这个以台网属于哪一个VLAN。
高速以太网主要是分为三种,即100BASE-T以太网、吉比特以太网和10吉比特以太网:
㈡ 邻接表的网络存储空间很大吗
在具体讲解邻接表存储图的实现方法之前,先普及一个"邻接点"的概念。在图中,如果两个点相互连通,即通过其中一个顶点,可直接找到另一个顶点,则称它们互为邻接点。
邻接指的是图中顶点之间有边或者弧的存在。
邻接表存储图的实现方式是,给图中的各个顶点独自建立一个链表,用节点存储该顶点,用链表中其他节点存储各自的临界点。
与此同时,为了便于管理这些链表,通常会将所有链表的头节点存储到数组中(也可以用链表存储)。也正因为各个链表的头节点存储的是各个顶点,因此各链表在存储临界点数据时,仅需存储该邻接顶点位于数组中的位置下标即可。
例如,存储图 1a) 所示的有向图,其对应的邻接表如图 1b) 所示:
邻接表存储有向图
图 1 邻接表存储有向图
拿顶点 V1 来说,与其相关的邻接点分别为 V2 和 V3,因此存储 V1 的链表中存储的是 V2 和 V3 在数组中的位置下标 1 和 2。
从图 1 中可以看出,存储各顶点的节点结构分为两部分,数据域和指针域。数据域用于存储顶点数据信息,指针域用于链接下一个节点,如图 2 所示:
邻接表节点结构
图 2 邻接表节点结构
在实际应用中,除了图 2 这种节点结构外,对于用链接表存储网(边或弧存在权)结构,还需要节点存储权的值,因此需使用图 3 中的节点结构:
邻接表存储网结构使用的节点
图 3 邻接表存储网结构使用的节点
图 1 中的链接表结构转化为对应 C 语言代码如下:
#define MAX_VERTEX_NUM 20//最大顶点个数
#define VertexType int//顶点数据的类型
#define InfoType int//图中弧或者边包含的信息的类型
typedef struct ArcNode{
int adjvex;//邻接点在数组中的位置下标
struct ArcNode * nextarc;//指向下一个邻接点的指针
InfoType * info;//信息域
}ArcNode;
typedef struct VNode{
VertexType data;//顶点的数据域
ArcNode * firstarc;//指向邻接点的指针
}VNode,AdjList[MAX_VERTEX_NUM];//存储各链表头结点的数组
typedef struct {
AdjList vertices;//图中顶点的数组
int vexnum,arcnum;//记录图中顶点数和边或弧数
int kind;//记录图的种类
}ALGraph;
邻接表计算顶点的出度和入度
使用邻接表计算无向图中顶点的入度和出度会非常简单,只需从数组中找到该顶点然后统计此链表中节点的数量即可。
而使用邻接表存储有向图时,通常各个顶点的链表中存储的都是以该顶点为弧尾的邻接点,因此通过统计各顶点链表中的节点数量,只能计算出该顶点的出度,而无法计算该顶点的入度。
对于利用邻接表求某顶点的入度,有两种方式:
遍历整个邻接表中的节点,统计数据域与该顶点所在数组位置下标相同的节点数量,即为该顶点的入度;
建立一个逆邻接表,该表中的各顶点链表专门用于存储以此顶点为弧头的所有顶点在数组中的位置下标。比如说,建立一张图 1a) 对应的逆邻接表:
逆邻接表示意图
对于具有 n 个顶点和 e 条边的无向图,邻接表中需要存储 n 个头结点和 2e 个表结点。在图中边或者弧稀疏的时候,使用邻接表要比前一节介绍的邻接矩阵更加节省空间。
回答于 2022-11-01
抢首赞
老人用哪种造口袋方便-淘宝热卖好物汇集,品牌众多,放心购!
【买3送5】造口袋封条造口护理用品防漏夹子造瘘袋便袋封口条10根
¥42.75 元
怡康一件式开口造口袋造瘘袋人工肛门袋大便袋10个送尾夹2
¥50 元
造口裤挂尿袋裤子老年人裤膀胱造瘘胆手术后护理专用裤春夏薄款
¥116 元
造瘘裤病人护理裤肾造口肠道造口老人护理用品病人手术后装尿袋裤
¥150 元
造瘘裤尿袋裤造口裤膀胱手术装尿袋引流袋裤子病人护理裤老人专用
¥96 元
淘宝热卖广告
哪个牌子好护肤品-上淘宝选好物,轻松下单,放心购物!
哪个牌子好护肤品-淘宝热卖好物,大牌汇聚,畅享购物!热卖优质商品,淘你满意!
淘宝热卖广告
护肤品有哪些品牌-淘宝热卖好物汇集,品牌众多,放心购!
护肤品有哪些品牌-购物上淘宝,品类集结,热卖好物!海量优质商品,轻松畅购!尽享优惠,买东西上淘宝,一站轻松购!
广告
数据结构,求无向图用邻接矩阵和邻接表的存储空间大小,怎么算?
邻接表所需的存储空间为e(边数),但不适合查询两点间是否存在路径邻接矩阵所需的存储空间为你n^2,适合查询两点间是否存在路径对于第二问,邻接表所需的存储空间为9900,邻接矩阵所需的存储空间为你n^2=10000,差不多,所以选性能更优的邻接矩阵实际上像(2)这种稠密图(其实是个满图)一般适合邻接矩阵
司马刀剑
1点赞1评论
更多专家
邻接表的网络存储空间很大吗
专家1对1在线解答问题
5分钟内响应 | 万名专业答主
马上提问
最美的花火 咨询一个电子数码问题,并发表了好评
lanqiuwangzi 咨询一个电子数码问题,并发表了好评
garlic 咨询一个电子数码问题,并发表了好评
188****8493 咨询一个电子数码问题,并发表了好评
篮球大图 咨询一个电子数码问题,并发表了好评
动物乐园 咨询一个电子数码问题,并发表了好评
AKA 咨询一个电子数码问题,并发表了好评
图解:什么是“图”?
作为图的开始,我们先来看一个经典的问题,它被认为是图论的起源。 欧拉在1735年提出,并没有方法能圆满解决这个问题,他更在第二年发表在论文《柯尼斯堡的七桥》中,证明符合条件的走法并不存在 欧拉把实际的抽象问题简化为平面上的点与线组合,每一座桥视为一条线,桥所连接的地区视为点。这样若从某点出发后最后再回到这点,则这一点的线数必须是偶数,这样的点称为偶顶点。相对的,连有奇数条线的点称为奇顶点。由于柯尼斯堡七桥问题中存在4个奇顶点,它无法实现符合题意的遍历。 之后,不少数学家都尝试去解析这类事例。而这些解析,最后发展成为了数学中的图论233。 图是一种非线性表数据结构,图中的元素我们叫做顶点,图中建立的连接关系我们叫做边。,图主要分为四种:无向图、有向图、加权图、加权有向图。 我们把有边有方向的图叫做“有向图”,把边没有方向的图叫做“无向图”,把边带有权重的图叫做“加权图”,这些概念其实都比较容易理解,你可以参考下面的几幅图对比一下。我们可以分别类比生活中的:知乎关注(有向)、微信交友(无向)和QQ好友亲密度(带权值)。 在图的表示中,我们定义 度 的概念。对于无向图而言,一个顶点的 度 是指跟该顶点相连接的边的条数;对于有向图而言,我们分别定义 入度 和 出度 ,顶点的入度表示有多少条边指向这个节点,顶点的出度表示有多少条边以这个节点为起点指向其他节点。 图的存储方法主要有两种:邻接表(Adjacency List)和邻接矩阵(Adjacency Matrix)。我们首先来介绍一下这两种存储方法。 邻接矩阵,顾名思义,就是利用矩阵去描述图,它的底层依赖于一个二维数组。对于无向图而言,如果 顶点i 与 顶点j 之间有边,那么我们就把 A[i][j] 和 A[j][i] 标记为1,它们之间没有边就标记为0;对于有向图而言,如果 顶点 i 到 顶点 j 之间,有一条箭头从 顶点 i 指向 顶点 j 的边,那我们就将 A[i][j] 标记为 1。同理,如果有一条箭头从 顶点j 指向 顶点 i 的边,我们就将 A[j][i] 标记为 1。对于带权图,数组中就存储相应的权重。 我们使用邻接矩阵来表示图,虽然的确很直观明了,但是却比较浪费空间。 其一,对于无向图来说, A[i][j] 永远等于 A[j][i] ,我们只需要使用一半矩阵就可以成功地表示,那另一半空间就被浪费掉了; 其二、如果我们存储的是稀疏图,也就是顶点很多,但每个顶点的边并不很多,此时邻接矩阵的存储方法就更加浪费空间了。好比微信有好几亿的用户,对应到图上就是好几亿的顶点。但是每个用户的好友并不会很多,一般也就几百个而已。如果我们用邻接矩阵来存储,那绝大部分的存储空间都被浪费了。 总结一下,当图为稀疏图、顶点较多,即图结构比较大时,更适宜选择邻接表作为存储结构。当图为稠密图、顶点较少时,使用邻接矩阵作为存储结构较为合适。 我们使用一个以顶点为索引的列表数组,其中数组中的每个元素都指向一个单独的链表,该链表存储了与数组中顶点相邻的所有顶点。有点绕口,不过我为你准备了一张图,我相信结合图片你肯定可以更好地理解。 相比于邻接矩阵, 邻接表比较节省存储空间,但是使用起来却比较耗费时间 。不过, 它的形式更为自由和灵活 ,比如,在链表过长的情况下,我们可以把链表用平衡二叉查找树(红黑树)替代,这样的话就比较高效了。 好了,关于图的内容就到这里了,我希望通过这篇文章你对于图有了一个初步的认识!下一次,我们会介绍深度优先搜索和广度优先搜索,小超与你不见不散!
㈢ 如何运用西门子PLC的变量存储器及什么程序能用到
用西门子PLC的变量存储器V只有S7- 200中才有。相当于300中的M变量。按v1,v2,v3 字节搞下去。
变量存储器(V)(相当于内辅继电器)PLC执行程序过程中,会存在一些控制过程的中间结果,这些中间数据也需要用存储器来保存。变量存储器就是根据这个实际的要求设计的。变量存储器是S7-200CPU为保存中间变量数据而建立的一个存储区,用V表示。可以按位、字节、字、双字四种方式来存取。(1)按“位”方式:从V0.0~I5119.7,共有40960点。CPU221、CPU222变量存储器只有2048个字节,其变量存储区只能到V2047.7位。(2)按“字节”方式:从VB0~VB5119,共有5120个字节(3)按“字”方式:从VW0~VW5118,共有2560个字(4)按“双字”方式:从VD0~VD5116,共有1280个双字
(1) S7-200存储器类型
S7-200 PLC可以采用多种形式的存储器来进行PLC程序与数据的存储,以防止数据的丢失。S7-200可以使用的存储器主要有如下类型:
①RAM: CPU模块本身带有动态数据存储器(RAM)。RAM用于存储PLC的运算、处理结果等数据。根据需要,RAM的数据可以通过电容器或电池盒(选件)进行保持,但其存储时间较短,一般只能保持几天。
②EEPROM(或Flash ROM):除RAM外,CPU模块本身带有的保持型存储器(EEPROM或Flash ROM),可以进行数据的永久性存储。保持型存储器用于存储PLC用户程序、PLC参数等重要数据;根据需要,也可以将PLC程序执行过程中所产生的局部变量V、内部标志M、定时器T、计数器C等保存在保持型存储器中。
③存储器卡:存储器卡在S7-200中为可选件,用户可以根据需要选用。存储器卡为保持型存储器,可以作为PLC保持型存储器的扩展与后备,用于保存PLC用户程序、PLC参数、变量V、内部标志M、定时器T、计数器C等。 (2)存储器分区
S7-200的内部存储器分为程序存储区、数据存储区、参数存储区。其中,程序存储区用于存储PLC用户程序;数据存储区用于存储PLC运算、 处理的中间结果(如输入/输出映像,标志、变量的状态,计数器、定时器的中间值等);参数存储区用于存储PLC配置参数(包括程序保护密码、地址分配设 定、停电保持区域的设定等)。
㈣ 哈密顿回路的算法
哈密顿路径问题在上世纪七十年代初,终于被证明是“NP完备”的。据说具有这样性质的问题,难于找到一个有效的算法。实际上对于某些顶点数不到100的网络,利用现有最好的算法和计算机也需要比较荒唐的时间(比如几百年)才能确定其是否存在一条这样的路径。
从图中的任意一点出发,路途中经过图中每一个结点当且仅当一次,则成为哈密顿回路。
要满足两个条件:
⒈封闭的环
⒉是一个连通图,且图中任意两点可达
经过图(有向图或无向图)中所有顶点一次且仅一次的通路称为哈密顿通路。
经过图中所有顶点一次且仅一次的回路称为哈密顿回路。
具有哈密顿回路的图称为哈密顿图,具有哈密顿通路但不具有哈密顿回路的图称为半哈密顿图。
平凡图是哈密顿图。
⒊若以1到2、2到3、3到4、4到5、5到1,为计数规律,则各点均出现两次;这种判断方法在计算机编程运算中显得尤为重要,其会精简很多运算过程。
⒋新出炉,有待检测的代码如下:
%-------输入的数据的原数据参照
% v1 v2 v3 v4 v5
%v1 0 20 1 11 2
%v2 0 0 9 1 3
%v3 0 0 0 13 8
%v4 0 0 0 0 6
%v5 0 0 0 0 0
%以上为输入数据的原数据参照
%建议所计算的数据矩阵长度为5,不会产生bug,且不会对任何计算机造成计算负担
%输入数据矩阵长度可以超过5,但是最初计算出的n个最小值中,重复次数超过2的点的种类只允许为一种
a=[0 20 1 11 2
0 0 9 1 3
0 0 0 13 8
0 0 0 0 6
0 0 0 0 0];
l=length(a)
s1=inf
zp=inf
n2=1
f=a
f(a==0)=inf
b=zeros(l)
i1=0
while i1<=l-1
[r c]=find(f==min(min(f)))
b(r⑴,c⑴)=f(r⑴,c⑴)
f(r⑴,c⑴)=inf
i1=i1+1
end
f1=f
[rz cz]=find(b>0)
pathz=[rz cz]
pz=[rz;cz]
p2z=zeros(2*l,1)
i2z=1
n2z=0
while i2z<=2*l
[r2z c2z]=find(pz==pz(i2z,1))
k1z=size(r2z)
if k1z(1,1)>2
p2z(r2z,1)=pz(r2z,1)
n2z=n2z+1
end
i2z=i2z+1
end
if n2z==2
HHL=b
zp=sum(sum(b))
else
while min(min(f1))~=inf
if n2>2
b=snh
end
[r1 c1]=find(b>0)
path1=[r1 c1]
p1=[r1;c1]
p2=zeros(2*l,1)
i2=1
n2=0
while i2<=2*l
[r2 c2]=find(p1==p1(i2,1))
k1=size(r2)
if k1(1,1)>2
p2(r2,1)=p1(r2,1)
n2=n2+1
end
i2=i2+1
end
[r3 c3]=find(p2>0)
p3=zeros(l,2)
i3=0
while i3<=n2-1
if r3⑴<=l
p3(r3⑴,:)=path1(r3⑴,:)
else
p3(r3⑴-l,:)=path1(r3⑴-l,:)
end
r3⑴=[]
i3=i3+1
end
p3(p3==0)=[]
p3=reshape(p3,n2,2)
p8=p2
[r8 c8]=find(p8>0)
p9=p8
r9=r8
i4=1
while i4<=n2
f1(p9(r9⑴,1),:)=inf
f1(:,p9(r9⑴,1))=inf
r9⑴=[]
i4=i4+1
end
[r4 c4]=find(f1==min(min(f1)))
f1(r4,c4)=inf
b1=b
b1(r4,c4)=a(r4,c4)
i5=1
p4=p3
while i5<=n2
b1=b
b1(r4⑴,c4⑴)=a(r4⑴,c4⑴)
b1(p4(1,1),p4(1,2))=0
p4(1,:)=[]
[r5 c5]=find(b1>0)
p5=[r5;c5]
i6=1
n6=0
while i6<=2*l
[r6 c6]=find(p5==p5(i6,1))
k6=size(r6)
if k6(1,1)>2
n6=n6+1
end
i6=i6+1
end
if n6>2
if sum(sum(b1))<s1
snh=[]
s1=sum(sum(b1))
snh=b1
end
else
if sum(sum(b1))<zp
HHL=[]
zp=sum(sum(b1))
HHL=b1
end
end
i5=i5+1
end
end
[rs cs]=find(HHL>0)
minpaths=[rs cs]
journeys=zp
注:这段代码采用分支定界法作为编写程序的依据,因此代码依旧局限在算法上;而且代码的使用对所要计算的数据是有要求的,如下:
⒈只要数据在开始计算出的n个最小值中,其重复次数超过2次的点的种类只能为一种,例如:代码段中的数据五个最小值中其重复次数超过2次的点只有v5。
⒉数据矩阵格式要求:只允许为上三角矩阵,不支持全矩阵以及下三角矩阵的运算。
⒊代码扩展方法请使用者独立思考,不唯一。
⒋运算数据扩展方法,请使用者独立思考,不唯一。
⒌此代码为本人毕设的附加产品,不会对使用此代码者,因理解不当或使用不当而造成的任何不良后果,付出任何责任。
⒍代码仅供交流。
㈤ 在AT89C51系列单片机内有几类存储器存储容量分别是多少
MCS-51单片机在物理结构上有四个存储空间: 1、片内程序存储器 2、片外程序存储器 3、片内数据存储器 4、片外数据存储器 但在逻辑上,即从用户的角度上,8051单片机有三个存储空间: 1、片内外统一编址的64K的程序存储器地址空间(MOVC) 2、256B的片内数据存储器的地址空间(MOV) 3、以及64K片外数据存储器的地址空间(MOVX) 在访问三个不同的逻辑空间时,应采用不同形式的指令以产生不同的存储器空间的选通信号。程序ROM 寻址范围:0000H ~ FFFFH 容量64KB EA = 1,寻址内部ROM;EA = 0,寻址外部ROM 地址长度:16位 作用: 存放程序及程序运行时所需的常数 数据存储器片内数据存储器为8位地址,所以最大可寻址的范围为256个单元地址,对片外数据存储器采用间接寻址方式,R0、R1和DPTR都可以做为间接寻址寄存器,R0、R1是8位的寄存器,即R0、R1的寻址范围最大为256个单元,而DPTR是16位地址指针,寻址范围就可达到64KB。也就是说在寻址片外数据存储器时,寻址范围超过了256B,就不能用R0、R1做为间接寻址寄存器,而必须用DPTR寄存器做为间接寻址寄存器。其中片内数据存储器分为两部分,地址从00H—7FH单元(共128个字节)为用户数据RAM,从80H—FFH地址单元(也是128个字节)为特殊寄存器(SFR)单元。
㈥ 东芝彩电21v2nc总线调整
1。更换存储器后,开机按遥控器上的静音键一次,同时按遥控上的静音和电视上的菜单,进入S。
2。此时同时按遥控上的屏显键和电视上的“节目+”完成初始化。
3。用频道键选项目,用音量键调数据。
㈦ 数据库解决了数据从逻辑结构到物理结构的存储问题对吗
数据结构有哪些》一节讲到,数据的存储方式可分为线性表、树和图三种存储结构,而每种存储结构又可细分为顺序存储结构和链式存储结构。数据存储方式如此之多,针对不同类型的数据选择合适的存储方式是至关重要的。
那么,到底如何选择呢?数据存储结构的选择取决于两方面,即数据的逻辑结构和存储结构(又称物理结构)。
逻辑结构
数据的逻辑结构,简单地理解,就是指的数据之间的逻辑关系。
家庭成员关系图
图 1 家庭成员关系图
例如,图 1 显示是一张家庭的成员关系图,从图中可以看到,张平、张华和张群是兄弟,他们的父亲是张亮,其中张平有两个儿子,分别是张晶和张磊。
以上所说,父子、兄弟等这些关系都指的是数据间的逻辑关系,假设我们要存储这样一张家庭成员关系图,不仅要存储张平、张华等数据,还要存储它们之间的关系,两者缺一不可。
一组数据成功存储到计算机的衡量标准是要能将其完整的复原。例如图 1 所示的成员关系图,如果所存储的数据能将此成员关系图彻底复原,则说明数据存储成功。
“多对多”关系示意图
图 2 “多对多”关系示意图
数据之间的逻辑关系可细分为三类,“一对一”、“一对多”和“多对多”:
“一对一”:类似集合 {1,2,3,...,n} 这类的数据,每个数据的左侧有且仅有一个数据与其相邻(除 1 外);同样,每个数据的右侧也只有一个数据与其相邻(除 n 外),所有的数据都是如此,就说数据之间是“一对一”的逻辑关系;
“一对多”:图 1 中的数据就属于“一对多”,因为对于张平来说,有且仅有一个父亲(张亮),但是有 2(多)个孩子;
“多对多”:拿图 2 来说,从 V1 可以到达 V2、V3、V4,同样,从 V2、V3、V4 也可以到达 V1,对于V1、V2、V3和V4来说,它们之间就是“多对多”的关系;
通过学习数据结构,我们可以学到 3 种存储结构分别存储这 3 类逻辑关系的数据,换句话说:
线性表用于存储具有“一对一”逻辑关系的数据;
树结构用于存储具有“一对多”关系的数据;
图结构用于存储具有“多对多”关系的数据;
由此,我们可以通过分析数据之间的逻辑关系来决定使用哪种存储结构,但具体使用顺序存储还是链式存储,还要通过数据的物理结构来决定。
存储结构(物理结构)
数据的存储结构,也就是物理结构,指的是数据在物理存储空间上选择集中存放还是分散存放。假设要存储大小为 10G 的数据,则集中存放就如图 3a) 所示,分散存放就如图 3b)所示。
数据的物理存储方式
图 3 数据的物理存储方式
如果选择集中存储,就使用顺序存储结构;反之,就使用链式存储。至于如何选择,主要取决于存储设备的状态以及数据的用途。
我们知道,集中存储(底层实现使用的是数组)需要使用一大块连续的物理空间,假设要存储大小为 1G 的数据,若存储设备上没有整块大小超过 1G 的空间,就无法使用顺序存储,此时就要选择链式存储,因为链式存储是随机存储数据,占用的都是存储设备中比较小的存储空间,因此有一定几率可以存储成功。
并且,数据的用途不同,选择的存储结构也不同。将数据进行集中存储有利于后期对数据进行遍历操作,而分散存储更有利于后期增加或删除数据。因此,如果后期需要对数据进行大量的检索(遍历),就选择集中存储;反之,若后期需要对数据做进一步更新(增加或删除),则选择分散存储。
㈧ 西门子200中数据块是怎么用的呀。请教,它的功能是什么呀
具体使用方法如下:
1、一般背景数据块才自动生成变量,是否可以改动或删除要看程序怎样写,如果程序没使用就可以删除,可以在原来基础上添加定义变量。
㈨ 数据结构——图
转自: http://www.cnblogs.com/mcgrady/archive/2013/09/23/3335847.html
阅读目录
一,图的定义
二,图相关的概念和术语
三,图的创建和遍历
四,最小生成树和最短路径
五,算法实现
这一篇我们要总结的是图(Graph),图可能比我们之前学习的线性结构和树形结构都要复杂,不过没有关系,我们一点一点地来总结,那么关于图我想从以下几点进行总结:
1,图的定义?
2,图相关的概念和术语?
3,图的创建和遍历?
4,最小生成树和最短路径?
5,算法实现?
一,图的定义
什么是图呢?
图是一种复杂的非线性结构。
在线性结构中,数据元素之间满足唯一的线性关系,每个数据元素(除第一个和最后一个外)只有一个直接前趋和一个直接后继;
在树形结构中,数据元素之间有着明显的层次关系,并且每个数据元素只与上一层中的一个元素(双亲节点)及下一层的多个元素(孩子节点)相关;
而在图形结构中,节点之间的关系是任意的,图中任意两个数据元素之间都有可能相关。
图G由两个集合V(顶点Vertex)和E(边Edge)组成,定义为G=(V,E)
二,图相关的概念和术语
1,无向图和有向图
对于一个图,若每条边都是没有方向的,则称该图为无向图。图示如下:
因此,(Vi,Vj)和(Vj,Vi)表示的是同一条边。注意,无向图是用小括号,而下面介绍的有向图是用尖括号。
无向图的顶点集和边集分别表示为:
V(G)={V1,V2,V3,V4,V5}
E(G)={(V1,V2),(V1,V4),(V2,V3),(V2,V5),(V3,V4),(V3,V5),(V4,V5)}
对于一个图G,若每条边都是有方向的,则称该图为有向图。图示如下。
因此,和是两条不同的有向边。注意,有向边又称为弧。
有向图的顶点集和边集分别表示为:
V(G)={V1,V2,V3}
E(G)={,,,}
2,无向完全图和有向完全图
我们将具有n(n-1)/2条边的无向图称为无向完全图。同理,将具有n(n-1)条边的有向图称为有向完全图。
3,顶点的度
对于无向图,顶点的度表示以该顶点作为一个端点的边的数目。比如,图(a)无向图中顶点V3的度D(V3)=3
对于有向图,顶点的度分为入度和出度。入度表示以该顶点为终点的入边数目,出度是以该顶点为起点的出边数目,该顶点的度等于其入度和出度之和。比如,顶点V1的入度ID(V1)=1,出度OD(V1)=2,所以D(V1)=ID(V1)+OD(V1)=1+2=3
记住,不管是无向图还是有向图,顶点数n,边数e和顶点的度数有如下关系:
因此,就拿有向图(b)来举例,由公式可以得到图G的边数e=(D(V1)+D(V2)+D(V3))/2=(3+2+3)/2=4
4,子图
故名思义,这个就不解释了。
5,路径,路径长度和回路
路径,比如在无向图G中,存在一个顶点序列Vp,Vi1,Vi2,Vi3…,Vim,Vq,使得(Vp,Vi1),(Vi1,Vi2),…,(Vim,Vq)均属于边集E(G),则称顶点Vp到Vq存在一条路径。
路径长度,是指一条路径上经过的边的数量。
回路,指一条路径的起点和终点为同一个顶点。
6,连通图(无向图)
连通图是指图G中任意两个顶点Vi和Vj都连通,则称为连通图。比如图(b)就是连通图。下面是一个非连通图的例子。
上图中,因为V5和V6是单独的,所以是非连通图。
7,强连通图(有向图)
强连通图是对于有向图而言的,与无向图的连通图类似。
8,网
带”权值”的连通图称为网。如图所示。
三,图的创建和遍历
1,图的两种存储结构
1) 邻接矩阵,原理就是用两个数组,一个数组保存顶点集,一个数组保存边集。下面的算法实现里边我们也是采用这种存储结构。如下图所示:
2) 邻接表,邻接表是图的一种链式存储结构。这种存储结构类似于树的孩子链表。对于图G中每个顶点Vi,把所有邻接于Vi的顶点Vj链成一个单链表,这个单链表称为顶点Vi的邻接表。
2,图的两种遍历方法
1) 深度优先搜索遍历
深度优先搜索DFS遍历类似于树的前序遍历。其基本思路是:
a) 假设初始状态是图中所有顶点都未曾访问过,则可从图G中任意一顶点v为初始出发点,首先访问出发点v,并将其标记为已访问过。
b) 然后依次从v出发搜索v的每个邻接点w,若w未曾访问过,则以w作为新的出发点出发,继续进行深度优先遍历,直到图中所有和v有路径相通的顶点都被访问到。
c) 若此时图中仍有顶点未被访问,则另选一个未曾访问的顶点作为起点,重复上述步骤,直到图中所有顶点都被访问到为止。
图示如下:
注:红色数字代表遍历的先后顺序,所以图(e)无向图的深度优先遍历的顶点访问序列为:V0,V1,V2,V5,V4,V6,V3,V7,V8
如果采用邻接矩阵存储,则时间复杂度为O(n2);当采用邻接表时时间复杂度为O(n+e)。
2) 广度优先搜索遍历
广度优先搜索遍历BFS类似于树的按层次遍历。其基本思路是:
a) 首先访问出发点Vi
b) 接着依次访问Vi的所有未被访问过的邻接点Vi1,Vi2,Vi3,…,Vit并均标记为已访问过。
c) 然后再按照Vi1,Vi2,… ,Vit的次序,访问每一个顶点的所有未曾访问过的顶点并均标记为已访问过,依此类推,直到图中所有和初始出发点Vi有路径相通的顶点都被访问过为止。
图示如下:
因此,图(f)采用广义优先搜索遍历以V0为出发点的顶点序列为:V0,V1,V3,V4,V2,V6,V8,V5,V7
如果采用邻接矩阵存储,则时间复杂度为O(n2),若采用邻接表,则时间复杂度为O(n+e)。
四,最小生成树和最短路径
1,最小生成树
什么是最小生成树呢?在弄清什么是最小生成树之前,我们需要弄清什么是生成树?
用一句语简单概括生成树就是:生成树是将图中所有顶点以最少的边连通的子图。
比如图(g)可以同时得到两个生成树图(h)和图(i)
知道了什么是生成树之后,我们就很容易理解什么是最小生成树了。所谓最小生成树,用一句话总结就是:权值和最小的生成树就是最小生成树。
比如上图中的两个生成树,生成树1和生成树2,生成树1的权值和为:12,生成树2的权值为:14,我们可以证明图(h)生成树1就是图(g)的最小生成树。
那么如何构造最小生成树呢?可以使用普里姆算法。
2,最短路径
求最短路径也就是求最短路径长度。下面是一个带权值的有向图,表格中分别列出了顶点V1其它各顶点的最短路径长度。
表:顶点V1到其它各顶点的最短路径表
从图中可以看出,顶点V1到V4的路径有3条(V1,V2,V4),(V1,V4),(V1,V3,V2,V4),其路径长度分别为15,20和10,因此,V1到V4的最短路径为(V1,V3,V2,V4)。
那么如何求带权有向图的最短路径长度呢?可以使用迪杰斯特拉(Dijkstra)算法。