图的最短路径、拓扑排序和关键路径

合集下载

数据结构的应用的拓扑排序与关键路径算法

数据结构的应用的拓扑排序与关键路径算法

数据结构的应用的拓扑排序与关键路径算法拓扑排序与关键路径算法是数据结构中重要的应用之一。

拓扑排序通过对有向图的节点进行排序,使得对于任意一条有向边(u,v),节点 u 在排序中都出现在节点 v 之前。

关键路径算法则是用来确定一个项目的关键活动和最短完成时间。

拓扑排序的实现可以通过深度优先搜索或者广度优先搜索来完成。

深度优先搜索是递归地访问节点的所有未访问过的邻居节点,直到没有未访问过的邻居节点为止,然后将该节点添加到拓扑排序的结果中。

广度优先搜索则是通过使用队列来实现的,将节点的邻居节点逐个入队并进行访问,直到队列为空为止。

无论使用哪种方法,拓扑排序都可以通过判断节点的入度来进行。

拓扑排序在很多实际问题中都有广泛应用。

比如在任务调度中,拓扑排序可以用来确定任务间的依赖关系和执行顺序;在编译原理中,拓扑排序可以用来确定程序中变量的定义和使用顺序。

关键路径算法用于确定项目中的关键活动和最短完成时间。

它通过计算每个活动的最早开始时间和最晚开始时间,以及每个活动的最早完成时间和最晚完成时间来实现。

具体步骤如下:1. 构建有向加权图,其中节点表示项目的活动,有向边表示活动间的先后关系,边的权重表示活动的持续时间。

2. 进行拓扑排序,确定活动的执行顺序。

3. 计算每个活动的最早开始时间,即从起始节点到该节点的最长路径。

4. 计算每个活动的最晚开始时间,即从终止节点到该节点的最长路径。

5. 根据每个活动的最早开始时间和最晚开始时间,可以确定关键活动,即最早开始时间与最晚开始时间相等的活动。

6. 计算整个项目的最短完成时间,即从起始节点到终止节点的最长路径。

拓扑排序与关键路径算法在工程管理、任务调度、生产流程优化等领域都有重要应用。

它们能够帮助我们有效地组织和管理复杂的项目,提高工作效率和资源利用率。

在实际应用中,我们可以借助计算机编程以及各种图算法库来实现这些算法,从而更快速、准确地解决实际问题。

综上所述,拓扑排序与关键路径算法是数据结构的重要应用之一。

图的概念

图的概念

V3
//第一行给给出边数和顶点数:n,m 。n和m的值均小于100 //第二行到n+1行,每一个行2个数,分别表示边的起点,终点。 //如 3,3 // 1 2 // 2 3 // 3 1 /*以邻接矩阵来存储。 #include <iostream> using namespace std; bool juzhen[101][101]; int main() { int m,n; cin>>m>>n; int a,b; for(int i=0;i<m;i++) { cin>>a>>b; juzhen[a][b]=1;// juzhen[b][a]=1; } }
如何用计算机来存储图的信息,这是图的存储结构 要解决的问题。 第一种:边集数组表示法。 定义一个结构体,存储边的起点和终点。 Struct bian { int s;//边的起点 int e;//边的终点 int v;//边的权值 } 然后定义一个该结构体的数组,存储图中所有的边。
第二种:邻接矩阵表示法。矩阵即二维数组。 设G=(V,E)是一个n阶图,顶点为 (V0,V1,……Vn-1).则可以定义一个n阶矩 阵arr[n][n]。即n行n列的二维数组。如果存 在边(Vi,Vj),则矩阵中arr[i][j]=1,否则 arr[i][j]=0.
这是著名的柯尼斯堡七桥问题。在一段时间内都没 有人能够给出正确答案。后来,欧拉证明了此题 是无解的。从而,引出了著名的“欧拉问题”或 “图的一笔画问题”。欧拉得出的结论是: 1.如果一个图中没有奇点,则该图可以从起点 出发经过所有边一次,再回到起点。 2.如果一个图中有且只有两个奇点,则该图可 以一个奇点出发,经过所有边一次,到达另一个 奇点。 欧拉开启了人们研究图的历史。

数据结构 图 练习题

数据结构 图 练习题

数据结构图练习题数据结构图练习题在计算机科学领域中,数据结构是一种用来组织和存储数据的方式。

而图是一种常见的数据结构,它由一组节点和连接这些节点的边组成。

图可以用来表示各种各样的关系,比如社交网络中的用户关系、城市之间的道路网络等等。

在本文中,我们将探讨一些与图相关的练习题,帮助读者更好地理解和应用图的概念。

1. 最短路径问题最短路径问题是图论中的经典问题之一。

给定一个带权重的有向图,我们需要找到从一个起始节点到目标节点的最短路径。

这里的权重可以表示为距离、时间或者其他度量。

解决这个问题的算法有很多,其中最著名的是Dijkstra算法和Bellman-Ford算法。

读者可以尝试使用这些算法来解决一些具体的实例,比如计算两个城市之间的最短路径。

2. 拓扑排序拓扑排序是对有向无环图(Directed Acyclic Graph,简称DAG)进行排序的一种算法。

在一个DAG中,节点之间存在一种偏序关系,即某些节点必须在其他节点之前进行处理。

拓扑排序可以帮助我们确定这种偏序关系,从而找到一种合理的处理顺序。

比如,在编译器中,拓扑排序可以用来确定源代码中各个函数的调用顺序。

读者可以尝试编写一个拓扑排序算法,并应用到一些具体的场景中。

3. 最小生成树最小生成树是一个无向连通图中一棵权值最小的生成树。

在一个连通图中,最小生成树可以帮助我们找到一种最优的连接方式,以满足一些约束条件。

最常用的算法是Prim算法和Kruskal算法。

读者可以尝试使用这些算法来解决一些具体的实例,比如在一个城市之间建设光纤网络,以最小的成本实现全覆盖。

4. 图的遍历图的遍历是指按照某种方式访问图中的所有节点。

常见的遍历算法有深度优先搜索(DFS)和广度优先搜索(BFS)。

DFS通过递归地访问每个节点的邻居节点,直到所有节点都被访问完。

BFS则通过队列来实现,先访问起始节点的邻居节点,然后依次访问它们的邻居节点,直到所有节点都被访问完。

数据库图

数据库图
对于无向图,其中任意两顶点都是连通的,则称 该无向图是连通图。无向图中的极大连通子图称为连 通分量。
V0
V2
V0
V4
V2
V4
V3
V5
V1
V3
V1
V5
无向图G3及连通分量
9
在有向图中,若任意两个顶点vi和vj都连通,则称该有向 图为强连通图。有向图的极大强连通子图称为强连通分量。
V0
V1
V1
V0
V2
图的定义和相关术语 图的存储 图的遍历 最小生成树 拓扑排序 最短路径 关键路径
2
7.1 图的基本概念 1.图的定义
图G (Graph)是由非空的顶点集合V(G)和描述顶点 之间关系的边集合E(G)构成,其形式定义为:G =(V(G),E(G))。简写为G=(V,E)。 G表示一个图,V是图G中非空顶点的集合,E是图G 中边的集合。
2.图的邻接矩阵的建立
图的邻接矩阵存储方法用一个二维数组存储顶点之间 的相邻关系,再用一个一维数组存储顶点信息,另外 还需要存储图的顶点数和边(弧)数。
12
typedef char Vextype;
typedef struct {
Vextype vexs[VEX_NUM];
int adj[MAXSIZE][MAXSIZE]; /*邻接矩阵*/
有向图:在一个图中,如果两个顶点构成的<vi, vj>∈E是序偶,则称这样的边是有向边,简称弧。用 <vi, vj>来表示。如果某图全部是由有向边构成,则称 该图为有向图。
4
无向完全图:在一个无向图中,设V是包含n个结
点的集合,且对于任意两个不相同的顶点之间都有
一条边将它们连接,则称该图为无向完全图。

上海海事大学828数据结构及程序设计2021年考研专业课初试大纲

上海海事大学828数据结构及程序设计2021年考研专业课初试大纲

3、栈和队列的应用
五、串
1、串的定义
2、串的存储结构及基本操作
3、串的应用
六、数组和广义表
1、数组和广义表的定义
2、数组和广义表的存储结构及基本操作
3、矩阵的压缩存储
4、数组和广义表的应用
七、树和二叉树
1、树的定义和基本操作
2、二叉树的定义、性质和存储结构及基本操作
3、遍历二叉树和线索二叉树
4、树和森林(存储结构、遍历、与二叉树的互相转换)
5、哈夫曼树及其应用
八、图
1、图的定义
2、图的存储结构
3、图的遍历
4、图的连通性(连通分量、最小生成树)
5、图的拓扑排序、关键路径、最短路径
九、查找
1、顺序表、有序表的查找及其分析
2、二叉排序树和平衡二叉树、B树
3、散列(Hash)表的定义、Hash函数的构造方式、冲突处理和Hash表的查找及其分析
十、内部排序
1、内部排序的基本概念
2、各种(插入类、交换类、选择类、归并类、基数排序)内部排序方法及其分析比较
3、外部排序的基本概念与方法
十一、文件
1、有关文件的基本概念
2、顺序文件、索引文件、索引顺序文件、直接存取文件、多重链表文件、倒排文件等的基本存取方法。

图论基础知识

图论基础知识
常州市第一中学 林厚从
图论算法与实现
一、图论基础知识
4、图的遍历: 对下面两个图分别进行深度优先遍历,写出遍历结果。 注意:分别从a和V1出发。
左图从顶点a出发,进行深度优先遍历的结果为:a,b,c,d,e,g,f 右图从V1出发进行深度优先遍历的结果为:V1,V2,V4,V8,V5,V3,V6,V7
邻接矩阵
边集数组
邻接表
优点O(1)
存储稀疏图时,空 间效率比较好,也 比较直观
便于查找任一顶点的关联边及 关联点,查找运算的时间复杂 性平均为O(e/n)
存储稀疏图,会造 成很大的空间浪费
不适合对顶点的运 算和对任意一条边 的运算
要查找一个顶点的前驱顶点和以此顶点 为终点的边、以及该顶点的入度就不方 便了,需要扫描整个表,时间复杂度为O (n+e)。可以用十字邻接表改进
被访问一次,这种运算操作被称为图的遍历。为了避免重复访问某个 顶点,可以设一个标志数组visited[i],未访问时值为false,访问一次 后就改为true。
图的遍历分为深度优先遍历和广度(宽度)优先遍历两种方法。 图的深度优先遍历:类似于树的先序遍历。从图中某个顶点Vi出发, 访问此顶点并作已访问标记,然后从Vi的一个未被访问过的邻接点Vj出 发再进行深度优先遍历,当Vi的所有邻接点都被访问过时,则退回到上 一个顶点Vk,再从Vk的另一个未被访问过的邻接点出发进行深度优先遍 历,直至图中所有顶点都被访问到为止。
常州市第一中学 林厚从
图论算法与实现
一、图论基础知识
4、图的遍历: 对于一个连通图,深度优先遍历的递归过程如下:
Procedure dfs(i:integer); {图用邻接矩阵存储} Begin
访问顶点i; Visited[i]:=True; For j:=1 to n do {按深度优先搜索的顺序遍历与i相关联的所有顶点}

拓扑排序及关键路径

拓扑排序及关键路径

2.有向图在实际问题中的应用 一个有向图可以表示一个施工流程图,或产品生产流程
图,或数据流图等。设图中每一条有向边表示两个子工程之 间的先后次序关系。
若以有向图中的顶点来表示活动,以有向边来表示活动 之间的先后次序关系,则这样的有向图称为顶点表示活动的 网 (Activity On Vertex Network),简称AOV网。
这样,每个活动允许的时间余量就是l(i) - e(i)。而关键活动 就是l(i) - e(i) = 0的那些活动,即可能的最早开始时间e(i)等于 允许的最晚开始时间l(i)的那些活动就是关键活动。
4.寻找关键活动的算法 求AOE网中关键活动的算法步骤为: (1)建立包含n+1个顶点、e条有向边的AOE网。其中,顶
(4)从汇点vn开始,令汇点vn的最晚发生时间vl[n]=ve[n], 按逆拓扑序列求其余各顶点k(k=n-1,n-2,…,2,1,0)的最晚发生 时间vl[k];
(5)计算每个活动的最早开始时间e[k] (k=1,2,3,…,e); (6)计算每个活动的最晚开始时间l[k] (k=1,2,3,…,e); (7)找出所有e[k]= l[k]的活动k,这些活动即为AOE网的 关键活动。
上述算法仅能得到有向图的一个拓扑序列。改进上述 算法,可以得到有向图的所有拓扑序列。
如果一个有向图存在一个拓扑序列,通常表示该有向 图对应的某个施工流程图的一种施工方案切实可行;而 如果一个有向图不存在一个拓扑序列,则说明该有向图 对应的某个施工流程图存在设计问题,不存在切实可行 的任何一种施工方案。
事件可能的最早开始时间υe(k):对于顶点υk代表的事件, υe(k)是从源点到该顶点的最大路径长度。在一个有n+1个事 件的AOE网中, 源点υ0的最早开始时间υe(0)等于0。事件υk (k=1,2,3,…,n)可能的最早开始时间υe(k)可用递推公式表 示为:

图_拓扑排序关键路径最短路径

图_拓扑排序关键路径最短路径
9.1静态查找表 静态查找表
6 a 5 d 4
b
1 1 e
8 7
g 4 h
2 k
c 2 4 f
a b c d e f g h k ve vl
0 0 0 0 0 0 15 14 18 6 4 5 5 7 0 11 0 7 0 18 18 18 18 18 18 18 18 18 0 6 6 8 8 10 16 14 7
事件发生时间的计算公式: 事件发生时间的计算公式: ve(源点 = 0; 源点) 源点 ; ve(j) = Max{ve(i) + dut(<i, j>)} <i,j>表示以 为弧头的弧 表示以j为弧头的弧 表示以 vl(汇点 = ve(汇点 ; 汇点) 汇点); 汇点 汇点 vl(i) = Min{vl(j) – dut(<i, k>)} <i,j>表示以 为弧尾的弧 表示以i为弧尾的弧 表示以
(2)弗洛伊德算法的基本思想是:
的所有可能存在的路径中, 从 vi 到 vj 的所有可能存在的路径中,选出一条长 度最短的路径。
可以用如下递推公式描述: 可以用如下递推公式描述: D-1[i][j]=cost[i][j] Dk [i][j]=min{Dk-1[i][j],Dk-1[i][k]+Dk-1[k][j]}(0≤k≤n-1) 其中, 中存放着序号为i的结点到序号为 其中,cost[i][j]中存放着序号为 的结点到序号为 的结点之 中存放着序号为 的结点到序号为j的结点之 表示从结点vi到结点 到结点vj的路径 间的权值 ; Dk[i][j](0≤k≤n-1) 表示从结点 到结点 的路径 上所经过的结点序号不大于k的最短路径长度 的最短路径长度。 上所经过的结点序号不大于 的最短路径长度。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数据结构课程辅导---图的最短路径、拓扑排序和关键路径一、最短路径由图的概念可知,在一个图中,若从一顶点到另一顶点存在着一条路径(这里只讨论无回路的简单路径),则称该路径长度为该路径上所经过的边的数目,它也等于该路径上的顶点数减1。

由于从一顶点到另一顶点可能存在着多条路径,每条路径上所经过的边数可能不同,即路径长度不同,我们把路径长度最短(即经过的边数最少)的那条路径叫做最短路径,其路径长度叫做最短路径长度或最短距离。

上面所述的图的最短路径问题只是对无权图而言的,若图是带权图,则把从一个顶点i到图中其余任一个顶点j的一条路径上所经过边的权值之和定义为该路径的带权路径长度,从vi到vj可能不止一条路径,我们把带权路径长度最短(即其值最小)的那条路径也称作最短路径,其权值也称作最短路径长度或最短距离。

例如,在图3-1中,从v0到v4共有三条路径:{0,4},{0,1,3,4}和{0,1,2,4},其带权路径长度分别为30,23和38,可知最短路径为{0,1,3,4},最短距离为23。

图3-1 带权图和对应的邻接矩阵实际上,这两类最短路径问题可合并为一类,这只要把无权图上的每条边标上数值为1的权就归属于有权图了,所以在以后的讨论中,若不特别指明,均认为是求带权图的最短路径问题。

求图的最短路径问题用途很广。

例如,若用一个图表示城市之间的运输网,图的顶点代表城市,图上的边表示两端点对应城市之间存在着运输线,边上的权表示该运输线上的运输时间或单位重量的运费,考虑到两城市间的海拔高度不同,流水方向不同等因素,将造成来回运输时间或运费的不同,所以这种图通常是一个有向图。

如何能够使从一城市到另一城市的运输时间最短或者运费最省呢?这就是一个求两城市间的最短路径问题。

求图的最短路径问题包括两个方面:一是求图中一顶点到其余各顶点的最短路径,二是求图中每对顶点之间的最短路径。

下面分别进行讨论。

1. 从一顶点到其余各顶点的最短路径对于一个具有n个顶点和e条边的图G,从某一顶点vi(称此为源点)到其余任一顶点vj(称此为终点)的最短路径,可能是它们之间的边(i,j)或<i,j>,也可能是经过k个(1≤k≤n-2,最多经过除源点和终点之外的所有顶点)中间顶点和k+1条边所形成的路径。

例如在图3-1中,从v0到v1的最短路径就是它们之间的有向边<0,1>,其长度为3;从v0到v4的最短路径经过两个中间点v1和v3以及三条有向边<0,1>,<1,3>和<3,4>,其长度为23。

那么,如何求出从源点i到图中其余每一个顶点的最短路径呢?狄克斯特拉(Dijkstra)于1959年提出了解决此问题的一般算法,具体做法是按照从源点到其余每一顶点的最短路径长度的升序依次求出从源点到各顶点的最短路径及长度,每次求出从源点i到一个终点m的最短路径及长度后,都要以该顶点m作为新考虑的中间点,用vi到vm的最短路径和最短路径长度对vi到其它尚未求出最短路径的那些终点的当前最短路径及长度作必要地修改,使之成为当前新的最短路径和最短路径长度,当进行n-2次(因最多考虑n-2个中间点)后算法结束。

狄克斯特拉算法需要设置一个集合,假定用S表示,其作用是保存已 2求得最短路径的终点序号,它的初值中只有一个元素,即源点i,以后每求出一个从源点i到终点m的最短路径,就将该顶点m并入S集合中,以便作为新考虑的中间点;还需要设置一个整型(假定权值类型为整型)数组dist[MaxVertexNum],该数组中的第j个元素dist[j]用来保存从源点i到终点j的目前最短路径长度,它的初值为(i,j)或<i,j>边上的权值,若vi到vj没有边,则权值为MaxValue,以后每考虑一个新的中间点时,dist[j]的值可能变小;另外,再设置一个与dist数组相对应的、类型为adjlist的邻接表表头向量数组path,该数组中的第j个元素path[j]指向一个单链表,该单链表中保存着从源点i到终点j的目前最短路径,即一个顶点序列,当vi到vj存在着一条边时,则path[j]初始指向由顶点i和j构成的单链表,否则path[j]的初值为空。

此算法的执行过程是:首先从S集合以外的顶点(即待求出最短路径的终点)所对应的dist数组元素中,查找出其值最小的元素,假定为dist[m],该元素值就是从源点i到终点m的最短路径长度(证明从略),对应path数组中的元素path[m]所指向的单链表链接着从源点i到终点m的最短路径,即经过的顶点序列或称边序列;接着把已求得最短路径的终点m并入集合S中;然后以vm作为新考虑的中间点,对S集合以外的每个顶点j,比较dist[m]+GA[m][j](GA为图G的邻接矩阵)与dist[j]的大小,若前者小于后者,表明加入了新的中间点vm之后,从vi到vj的路径长度比原来变短,应用它替换dist[j]的原值,使dist[j]始终保持到目前为止最短的路径长度,同时把path[m]单链表复制到path[j]上,并在其后插入vj结点,使之构成从源点i到终点j的目前最短路径。

重复n-2次上述运算过程,即可在dist数组中得到从源点i到其余每个顶点的最短路径长度,在path数组中得到相应的最短路径。

为了简便起见,可采用一维数组s[n]来保存已求得最短路径的终点的集合S,具体做法是:若顶点j在集合S中,则令数组元素s[j]的值取1,否则取0。

这样,当判断一个顶点j是否在集合S以外时,只要判断对应的数组元素s[j]是否为0即可。

例如,对于图3-1来说,若求从源点v0到其余各顶点的最短路径,则开始时三个一维数组s,dist和path的值为:0 1 2 3 4 s dist path下面开始进行第一次运算,求出从源点v0到第一个终点的最短路径。

首先从s元素为0的对应dist元素中,查找出值最小的元素,求得dist[2]的值最小,所以第一个终点为v1, 最短距离为dist[2]=3,最短路径为path[2]={0,1},接着把s[1]置为1,表示v1已加入S集合中,然后以v1为新考虑的中间点,对s数组中元素为0的每个顶点j(此时2≤j≤4)的目前最短路径长度dist[j]和目前最短路径path[j]进行必要地修改,因dist[1]+GA[1][2]=3+25=28,小于dist[2]=∞,所以将28赋给dist[2],将path[1]并上v2后赋给path[2],同理因dist[1]+GA[1][3]=3+8=11,小于dist[3]=∞,所以将11赋给dist[3],将path[1]并上v3后赋给path[3],最后再看从v0到v4,以v1作为新考虑的中间点的情况,由于v1到v4没有出边,所以GA[1][4]=∞,故dist[1]+GA[1][4]不小于dist[4],因此dist[4]和path[4]无需修改,应维持原值。

至此,第一次运算结束,三个一维数组的当前状态为:0 1 2 3 4 s dist path下面开始进行第二次运算,求出从源点v0到第二个终点的最短路径。

首先从s数组中元素为0的对应dist元素中,查找出值最小的元素,求得dist[3]的值最小,所以第二个终点为v3, 最短距离为dist[3]=11,最短路径为path[3]={0,1,3},接着把s[3]置为1,然后以v3作为新考虑的中间点,对s中元素为0的每个顶点j(此时j=3,5)的dist[j]和path[j]进行必要的修改,因dist[3]+GA[3][2]=11+4=15,小于dist[2]=28,所以将15赋给dist[2],将path[3]并上v2后赋给path[2],同理,因dist[3]+GA[3][4]=11+12=23,小于dist[4]=30,所以将23赋给dist[4],将path[3]并上v4后赋给path[4]。

至此,第二次运算结束,三个一维数组的当前状态为:0 1 2 3 4 s dist path下面开始进行第三次运算,求出从源点v0到第三个终点的最短路径。

首先从s中元素为0的对应dist元素中,查找出值最小的元素为dist[2],所以求得第三个终点为v2,最短距离为dist[2]=15,最短路径为path[2]={0,1,3,2},接着把s[2]置为1,然后以v2作为新考虑的中间点,对s中元素为0的每个顶点j(此时只有v4一个)的dist[j]和path[j]进行必要的修改,因dist[2]+GA[2][4]=15+10=25,大于dist[4]=23,所以无需修改,原值不变。

至此,第三次运算结束,三个一维数组的当前状态为:0 1 2 3 4 s dist path由于图中有5个顶点,只需运算3次,即n-2次,虽然此时还有一个顶点未加入S集合中,但它的最短路径及最短距离已经最后确定,所以整个运算结束。

最后在dist中得到从源v0到每个顶点的最短路径长度,在path中得到相应的最短路径。

如果用图形表示上述过程中每次运算的结果,则对应的图形分别如图3-2(b)~(e)所示,其中实线有向边所指向的顶点为集合S中的顶点,虚线有向边所指向的顶点为集合S外的顶点;S集合中的顶点上所标数值为从源点v0到该顶点的最短路径长度,从源点v0到该顶点所经过的有向边为从v0到该顶点的最短路径;S集合外的顶点上所标数值为从源点v0到该顶点的目前最短路径长度,从v0到该顶点所经过的有向边为从v0到该顶点的目前最短路径。

为了便于对照分析,把图3-1(a)重画于图3-2(a)中。

图3-2 利用狄克斯特拉算法求最短路径的图形说明根据以上分析和举例,不难给出狄克斯特拉算法的描述: void Dijkstra(adjmatrix GA, int dist[],adjlist path, int i, int n)//利用狄克斯特拉算法求图GA中从顶点i到其余每个顶点间的 //最短距离和最短路径,它们分别被存于数组dist和path数组中{int j,k,w,m;//定义作为集合使用的动态数组sint* s=new int[n];//分别给s,dist和path数组赋初值for(j=0; j<n; j++) {if(j==i)s[j]=1;elses[j]=0;dist[j]=GA[i][j];if(dist[j]<MaxValue && j!=i) {edgenode* p1=new edgenode;edgenode* p2=new edgenode;p1->adjvex=i;p2->adjvex=j;p2->next=NULL;p1->next=p2;path[j]=p1;}elsepath[j]=NULL;}//共进行n-2次循环,每次求出从源点i到终点m的最短路径及长度 for(k=1;k<=n-2; k++){//求出第k个终点mw=MaxValue; m=i;for(j=0; j<n; j++)if(s[j]==0 && dist[j]<w) {w=dist[j];m=j;}//若条件成立,则把顶点m并入集合S中,否则退出循环,因为剩余 //的顶点,其最短路径长度均为MaxValue,无需再计算下去 if(m!=i)s[m]=1;elsebreak;//对s元素为0的对应dist和path中的元素作必要修改 for(j=0; j<n; j++)if(s[j]==0 && dist[m]+GA[m][j]<dist[j]) { dist[j]=dist[m]+GA[m][j];PATH(path, m, j); //调用此函数,由到顶点m的 //最短路径和顶点j构成到顶点j 的目前最短路径 }}}PATH函数的定义如下:void PATH(adjlist path, int m, int j)//由到顶点m的最短路径和顶点j构成到顶点j的目前最短路径 {edgenode *p, *q, *s;//把顶点j的当前最短路径清除掉p=path[j];while(p!=NULL) {path[j]=p->next;delete p;p=path[j];}//把到顶点m的最短路径拷贝过来到顶点j的最短路径上 p=path[m];while(p!=NULL) {q=new edgenode;q->adjvex=p->adjvex;if(path[j]==NULL)path[j]=q;elses->next=q;s=q;p=p->next;}//把顶点j加入到path[j]单链表的最后,形成新的目前最短路径 q=new edgenode; q->adjvex=j;q->next=NULL;s->next=q;}2. 每对顶点之间的最短路径求图中每对顶点之间的最短路径是指把图中任意两个顶点vi和vj(i≠j)之间的最短路径都计算出来。

相关文档
最新文档