数据结构 学习笔记(八):图(中):最短路径问题(单源最短路径 Dijkstra,多源最短路径 Floyd)
来源:互联网 发布:蜂窝移动网络搜索定位 编辑:程序博客网 时间:2024/05/16 08:54
7.1 最短路径问题
7.1.1 概述
图论里最少的步骤就是最短路径问题。
最短路径问题的抽象
在网络中,求两个不同顶点之间的所有路径中,边的权值之和最小的那一条路径。这条路径就是两点之间的最短路径。
第一个顶点为源点,最后一个顶点为终点。
问题分类
单源最短路径问题:从某固定源点出发,求其到所有其他顶点的最短路径。
单源最短路径问题又分为两类:
- (有向)无权图
- (有向)有权图
多源最短路径问题:求任意两顶点间的最短路径。
7.1.2 无权图的单源最短路
思路:按照递增(非递减)的顺序找出各个顶点的最短路。 类似于 BFS算法。
算法
与 BFS算法相比较,体会不同。
假设我们是用邻接表存的。
C语言实现
/* 邻接表存储 - 无权图的单源最短路算法 *//* dist[]和path[]全部初始化为-1 */void Unweighted ( LGraph Graph, int dist[], int path[], Vertex S ){ Queue Q; Vertex V; PtrToAdjVNode W; Q = CreateQueue( Graph->Nv ); /* 创建空队列, MaxSize为外部定义的常数 */ dist[S] = 0; /* 初始化源点 */ AddQ (Q, S); while( !IsEmpty(Q) ){ V = DeleteQ(Q); for ( W=Graph->G[V].FirstEdge; W; W=W->Next ) /* 对V的每个邻接点W->AdjV */ if ( dist[W->AdjV]==-1 ) { /* 若W->AdjV未被访问过 */ dist[W->AdjV] = dist[V]+1; /* W->AdjV到S的距离更新 */ path[W->AdjV] = V; /* 将V记录在S到W->AdjV的路径上 */ AddQ(Q, W->AdjV); } } /* while结束*/}
7.1.3有权图的单源最短路(Dijkstra算法)
定义
按照递增的顺序找出到各个顶点的最短路。(Dijkstra算法)
Dijkstra算法
伪代码:
C语言实现
/* 邻接矩阵存储 - 有权图的单源最短路算法 */Vertex FindMinDist( MGraph Graph, int dist[], int collected[] ){ /* 返回未被收录顶点中dist最小者 */ Vertex MinV, V; int MinDist = INFINITY; for (V=0; V<Graph->Nv; V++) { if ( collected[V]==false && dist[V]<MinDist) { /* 若V未被收录,且dist[V]更小 */ MinDist = dist[V]; /* 更新最小距离 */ MinV = V; /* 更新对应顶点 */ } } if (MinDist < INFINITY) /* 若找到最小dist */ return MinV; /* 返回对应的顶点下标 */ else return ERROR; /* 若这样的顶点不存在,返回错误标记 */}bool Dijkstra( MGraph Graph, int dist[], int path[], Vertex S ){ int collected[MaxVertexNum]; Vertex V, W; /* 初始化:此处默认邻接矩阵中不存在的边用INFINITY表示 */ for ( V=0; V<Graph->Nv; V++ ) { dist[V] = Graph->G[S][V]; if ( dist[V]<INFINITY ) path[V] = S; else path[V] = -1; collected[V] = false; } /* 先将起点收入集合 */ dist[S] = 0; collected[S] = true; while (1) { /* V = 未被收录顶点中dist最小者 */ V = FindMinDist( Graph, dist, collected ); if ( V==ERROR ) /* 若这样的V不存在 */ break; /* 算法结束 */ collected[V] = true; /* 收录V */ for( W=0; W<Graph->Nv; W++ ) /* 对图中的每个顶点W */ /* 若W是V的邻接点并且未被收录 */ if ( collected[W]==false && Graph->G[V][W]<INFINITY ) { if ( Graph->G[V][W]<0 ) /* 若有负边 */ return false; /* 不能正确解决,返回错误标记 */ /* 若收录V使得dist[W]变小 */ if ( dist[V]+Graph->G[V][W] < dist[W] ) { dist[W] = dist[V]+Graph->G[V][W]; /* 更新dist[W] */ path[W] = V; /* 更新S到W的路径 */ } } } /* while结束*/ return true; /* 算法执行完毕,返回正确标记 */}
7.1.4 多源最短路算法(Floyd算法)
Floyd算法
C语言实现
/* 邻接矩阵存储 - 多源最短路算法 */bool Floyd( MGraph Graph, WeightType D[][MaxVertexNum], Vertex path[][MaxVertexNum] ){ Vertex i, j, k; /* 初始化 */ for ( i=0; i<Graph->Nv; i++ ) for( j=0; j<Graph->Nv; j++ ) { D[i][j] = Graph->G[i][j]; path[i][j] = -1; } for( k=0; k<Graph->Nv; k++ ) for( i=0; i<Graph->Nv; i++ ) for( j=0; j<Graph->Nv; j++ ) if( D[i][k] + D[k][j] < D[i][j] ) { D[i][j] = D[i][k] + D[k][j]; if ( i==j && D[i][j]<0 ) /* 若发现负值圈 */ return false; /* 不能正确解决,返回错误标记 */ path[i][j] = k; } return true; /* 算法执行完毕,返回正确标记 */}
阅读全文
0 0
- 数据结构 学习笔记(八):图(中):最短路径问题(单源最短路径 Dijkstra,多源最短路径 Floyd)
- 数据结构基础6.4:最短路径(Dijkstra, Floyd)
- 最短路径:(Dijkstra & Floyd)
- 最短路径(Dijkstra、Floyd)
- 最短路径(Dijkstra和Floyd)
- 数据结构学习笔记(八)--最短路径
- Floyd最短路径(多源最短路径)
- 图的最短路径(dijkstra算法/floyd算法)
- 数据结构之最短路径(Floyd)
- 数据结构之最短路径(Floyd)
- 数据结构--最短路径(Dijkstra算法)
- 数据结构之最短路径(DijKstra)
- Floyd(最短路径问题)
- 最短路径问题(Floyd算法)
- 最短路径问题(floyd算法)
- Floyd算法学习(最短路径)
- 最短路径问题(Dijkstra解法)
- 最短路径问题(Dijkstra算法)
- JavaWeb之Servlet开发(一)
- Angular的变化检测
- vs2012 在js 加断点进行调试无效果
- 分布式系统架构的基本原则和实践
- vue对比与其他框架
- 数据结构 学习笔记(八):图(中):最短路径问题(单源最短路径 Dijkstra,多源最短路径 Floyd)
- 递增的整数序列链表的插入
- 一、kafka简介
- [算法概论]习题8.12
- 算法 最大公因数
- 对焦算法实现总结
- 程序员高薪“盛宴”背后:人才结构性过剩和缺失共存
- redhat6.8 配置使用centos的yum源【增加脚本,直接root下运行即可】
- jackson自定义序列化过程