首页 > 编程知识 正文

数据结构prim算法(dijkstra最短路径算法表格)

时间:2023-05-04 20:46:41 阅读:66501 作者:4332

Dijkstra算法是典型的最短路径算法,并且被用于计算从一个节点到另一个节点的最短路径。

其主要特征是以起点为中心向外侧扩展层,扩展到终点(广度优先搜索思想)

# #基本思想

在通过戴克斯特拉计算图表g中的最短路径时,需要指定起点s (即根据顶点s计算)。

另外,引入两个集合s和u。 下一个作用是记录求出最短路径的顶点(及其对应的最短路径长度),u记录最短路径尚未求出的顶点)以及从该顶点到起点s的距离。

初始情况下,s只有起点s; 中是除去s的顶点,且u中的顶点的路径是“从起点s到该顶点的路径”。 然后,从u中找到路径最短的顶点,将其添加到s中; 接着,更新与u的顶点和顶点对应的路径。 然后,从u中找到路径最短的顶点,将其添加到s中; 接着,更新与u的顶点和顶点对应的路径。 …重复此操作,直到遍历所有顶点。

###

在初始情况下,s仅包含起点s; u中包含s以外的顶点,u中的顶点的距离为“从起点s到该顶点的距离”[例如u中的顶点v的距离为[s,v]的长度,并且如果s和v不邻接,则v的距离为]。

从u中选择“距离最短的顶点k”,将顶点k添加到s中; 同时,从u中删除顶点k。

更新从u的各顶点到起点s的距离。 更新u中顶点的距离是因为在上一步骤中确定了k是求出最短路径的顶点,因此可以利用k更新其他顶点的距离; 例如,(s,v )的距离可能大于() s,k ) )、v )的距离。

重复步骤(2)和(3),直到遍历所有顶点。

单纯看上面的理论可能很难理解,用实例说明这个算法。

# #图解

以上图G4为例,进行抖动算法的演示(以第四个顶点d为起点)。 以下b节点中的23个必须是13个。

初始状态: s是计算最短路径的顶点的集合,u是除去最短路径的顶点的集合!

步骤1 :将顶点d添加到s。

此时,s={d(0) }、u={a()、b )、c ) )、e )、4 )、f()、g ) (}。 注:c(3)表示从c到起点d的距离为3。

步骤2 :将顶点c添加到s。

在前一操作之后,从u顶点c到起点d的距离最短; 因此,将c加到s中,同时更新u中顶点的距离。 以顶点f为例,前面f到d的距离为; 但是,在将c加到s之后,从f到d的距离为9=(f,c ) ) c,d )。

此时,s={d(0),c ) },u={a(),b ) 23 ),e ),f ),9 ),g() }。

步骤3 :将顶点e添加到s。

在前一操作之后,从u顶点e到起点d的距离最短; 因此,将e加到s中,同时更新u中顶点的距离。 还是以顶点f为例,前面f到d的距离是9; 但是,在将e加到s之后,从f到d的距离为6=(f,e ) ) e,d )。

此时,s={d(0),c ),e ) },u={a(),b ),b ),f ),6 ),g ) }。

步骤4 :将顶点f添加到s。

此时,成为s={d(0)、c (3)、e ) 4、f ) }、u={a ) 22 )、b (13 )、g (12 )。

步骤5 :将顶点g添加到s。

此时,s={d(0)、c (3)、e (4)、f (6)、g ) }、u={a(22 )、b ) 13}。

步骤6 :将顶点b添加到s。

在这种情况下,s={d(0)、c (3)、e (4)、f (6)、g )、b ) },u={a ) 22}。

步骤7 :将顶点a添加到s。

在这种情况下,s={d(0)、c (3)、e (4)、f (6)、g )、b (13 )、a (22 )。

此时,从起点d到各顶点的最短距离计算为a(22 ) b ) 13 ) c )3) d )0) e )4) f )6) g ) 12 )。

###代码

以邻接矩阵为例,

//相邻矩阵typedef struct _ graph { charvexs [ max ]; //顶点集合int vexnum; //顶点数int edgnum; //边数int matrix[MAX][MAX]; //邻接矩阵(}Graph,*PGraph; //边的结构体typedef struct _ edgedata { charstart; //边缘的起点char end; //边的终点int weight; //边权重}EData; Graph是与邻接矩阵对应的结构体。

vexs用于保存顶点,vexnum是顶点数,edgnum是边数。 matrix是用于保持矩阵信息的二维数组。

例如,如果matrix[i][j]=1,则表示顶点I (即vexs[i] )和顶点j (即vexs[j] )是相邻节点。 matrix[i][j]=0表示不是相邻节点。

EData是与邻接矩阵的边对应的结构体。

# # # #

/* * Dijkstra最短路径。 *即,从统计图(g )的“顶点vs”到其他各顶点的最短路径。 *参数说明: * G --

图 * vs -- 起始顶点(start vertex)。即计算"顶点vs"到其它顶点的最短路径。 * prev -- 前驱顶点数组。即,prev[i]的值是"顶点vs"到"顶点i"的最短路径所经历的全部顶点中,位于"顶点i"之前的那个顶点。 * dist -- 长度数组。即,dist[i]是"顶点vs"到"顶点i"的最短路径的长度。 */void dijkstra(Graph G, int vs, int prev[], int dist[]){ int i,j,k; int min; int tmp; int flag[MAX]; // flag[i]=1表示"顶点vs"到"顶点i"的最短路径已成功获取。 // 初始化 for (i = 0; i < G.vexnum; i++) { flag[i] = 0; // 顶点i的最短路径还没获取到。 prev[i] = 0; // 顶点i的前驱顶点为0。 dist[i] = G.matrix[vs][i];// 顶点i的最短路径为"顶点vs"到"顶点i"的权。 } // 对"顶点vs"自身进行初始化 flag[vs] = 1; dist[vs] = 0; // 遍历G.vexnum-1次;每次找出一个顶点的最短路径。 for (i = 1; i < G.vexnum; i++) { // 寻找当前最小的路径; // 即,在未获取最短路径的顶点中,找到离vs最近的顶点(k)。 min = INF; for (j = 0; j < G.vexnum; j++) { if (flag[j]==0 && dist[j]<min) { min = dist[j]; k = j; } } // 标记"顶点k"为已经获取到最短路径 flag[k] = 1; // 修正当前最短路径和前驱顶点 // 即,当已经"顶点k的最短路径"之后,更新"未获取最短路径的顶点的最短路径和前驱顶点"。 for (j = 0; j < G.vexnum; j++) { tmp = (G.matrix[k][j]==INF ? INF : (min + G.matrix[k][j])); // 防止溢出 if (flag[j] == 0 && (tmp < dist[j]) ) { dist[j] = tmp; prev[j] = k; } } } // 打印dijkstra最短路径的结果 printf("dijkstra(%c): n", G.vexs[vs]); for (i = 0; i < G.vexnum; i++) printf(" shortest(%c, %c)=%dn", G.vexs[vs], G.vexs[i], dist[i]);}

###参考资料
1, http://www.cnblogs.com/skywang12345/p/3711512.html

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。