数据结构——图——最短路径D&F算法
一、Dijkstra算法(贪心地求最短距离的算法)
在此算法中,我按照自己的理解去命名,理解起来会轻松一些。
#define MAXSIZE 100
#define UNVISITED 0
#define VISITED 1
#define INFINITY 66666
typedef struct tool {
int visited[MAXSIZE];
/*是否已访问的数组,visited[i]表示顶点i已经访问,也就是到顶点i的最短距离已求出*/
int known_shortest_distance[MAXSIZE];
/*已知的最短距离数组。known_shortest_distance[i]代表从V0到Vi的最短距离*/
int previous_vertex[MAXSIZE];
/*previous_vertex[i]=j,代表:在从V0到Vi的最短路径上,顶点i的前一个顶点是顶点j*/
} Tool;
typedef struct gragh {
int num_of_vertexes;
int adjacent_matrix[MAXSIZE][MAXSIZE];
} Gragh;
void init_tool(Gragh g, Tool &t) {
;
; i < g.num_of_vertexes; i++) {
t.visited[i] = UNVISITED;
t.known_shortest_distance[i] = g.adjacent_matrix[][i];
t.previous_vertex[i] = ;
}
}
void dijstra_shortest_distance(Gragh g, Tool &t) {
int i, j, x; //循环变量
int min_distance, x_index;
/*min_distance存储的是当前已知的最短距离数组中从V0到Vx最小的距离;
x_index存储的Vx的下标*/
init_tool(g, t);
; i < g.num_of_vertexes; i++) {
min_distance = INFINITY;
; x < g.num_of_vertexes; x++) {
if(!t.visited[x] && t.known_shortest_distance[x] < min_distance) {
min_distance = t.known_shortest_distance[x];
x_index = x;
}
}
/*通过上面一个循环,最短距离数组中的最小值就是min_distance;
该顶点的下标就是x_index;
在当前没有访问且以V0为起点距离最短的顶点中,
这个点的下标就是x_index.*/
t.visited[x_index] = VISITED;
; j < g.num_of_vertexes; j++) {
if(!t.visited[j] && (min_distance + g.adjacent_matrix[x_index][j] < t.known_shortest_distance[j])) {
t.known_shortest_distance[j] = min_distance + g.adjacent_matrix[x_index][j];
t.previous_vertex[j] = x_index;
}
}
}
}
如果要求任意两点之间的最短距离:只需在外层加一层循环,把最短距离数组和previous_vertex数组变成二维数组即可。
输出从V0到Vi的最短距离和完整路径:
#include<stack>
void print_path(Tool &t, int dest) {
int i = dest;
stack<int> s;
cout << "从V0到V" << i << "的最短距离:" << t.known_shortest_distance[i] << endl;
) {
s.push(t.previous_vertex[i]);
i = t.previous_vertex[i];
}
cout << "从V0到V" << i << "的路径:";
cout<<"V0";
while(!s.empty()) {
cout << "->V" << s.top();
s.pop();
}
cout << "->V" << dest;
}
一、Floyd算法(不管三七二十一,先把整个图中任意两点的最短距离求出再说)
核心思想:对图中任意两个顶点(即下面代码中的j和k),如果能在其他顶点中(也就是下面代码中的i,在原始版本中,i和j,k可以相同)找到一个顶点i,使得顶点j到顶点i的距离加上顶点i的距离到顶点k的距离比直接从顶点j到顶点k的距离短,那么,就修改顶点j到顶点k的距离。
typedef struct floyd_tool {
int known_shortest_distance[MAXSIZE][MAXSIZE];
/*已知的最短距离数组。known_shortest_distance[i][j]代表从Vi到Vj的最短距离*/
int path_matrix[MAXSIZE][MAXSIZE];
/*path_matrix[i][j]=k,代表:在从Vi到Vj的最短路径上,要经过顶点k;
用k代替i,直到path_matrix[k][j]=j*/
} FloydTool;
void init_floyd_tool(FloydTool &ft, Gragh g) {
; i < g.num_of_vertexes; i++) {
; j < g.num_of_vertexes; j++) {
ft.known_shortest_distance[i][j] = g.adjacent_matrix[i][j];
ft.path_matrix[i][j] = j;
}
}
}
void floyd_shortest_distance(Gragh g,FloydTool &ft) {
init_floyd_tool(ft,g);
;i < g.num_of_vertexes; i++){
;j < g.num_of_vertexes;j++){
;k < g.num_of_vertexes;k++){
if(ft.known_shortest_distance[j][k] >
ft.known_shortest_distance[j][i] + ft.known_shortest_distance[i][k]){
ft.known_shortest_distance[j][k] =
ft.known_shortest_distance[j][i] + ft.known_shortest_distance[i][k];
ft.path_matrix[j][k] = ft.path_matrix[j][i];
}
}
}
}
}
改进版:
改进依据:由上面初始版本的思想可知,对于任意两个顶点j和顶点k,如果顶点j和顶点i是同一个,那么,最里面一层的比较相当于是D和0+D在比,显然,这是没必要的。或者,如果j和i不相等,但是i不是j的邻接点,那么j到i的距离就是“无穷大”,很显然,通过这个桥梁i是不可能缩短j到k的距离的。所以,有了第一个if;同理,第二个if也是这么来的。然后,初始版本中,最里面两层循环的循环变量都是从0开始的,但是因为我们考虑的是无向图,j到k的距离和k到j的距离是一样的,所以,我在改进版本中减去了重复求k到j的距离。
void floyd_shortest_distance(Gragh g,FloydTool &ft) {
init_floyd_tool(ft,g);
;i < g.num_of_vertexes; i++){
;j < g.num_of_vertexes;j++){
if(j == i || ft.known_shortest_distance[j][i] == INFINITY)continue;
for(int k = j + 1;k < g.num_of_vertexes;k++){
if(k == i || ft.known_shortest_distance[k][i] == INFINITY)continue;
if(ft.known_shortest_distance[j][k] >
ft.known_shortest_distance[j][i] + ft.known_shortest_distance[i][k]){
ft.known_shortest_distance[j][k] =
ft.known_shortest_distance[j][i] + ft.known_shortest_distance[i][k];
ft.path_matrix[j][k] = ft.path_matrix[j][i];
}
}
}
}
}
输出最短距离和完整路径:
void print_path(FloydTool &ft,int orig,int dest) {
cout << "从V"<<orig<<"到V"<<dest<< "的最短距离:" << ft.known_shortest_distance[orig][dest] << endl;
cout << "从V"<<orig<<"到V"<<dest<<"的路径:";
cout<<"V"<<orig;
while(ft.path_matrix[orig][dest] != dest){
cout<<"->V"<<ft.path_matrix[orig][dest];
orig = ft.path_matrix[orig][dest];
}
cout << "->V" << dest;
}
数据结构——图——最短路径D&F算法的更多相关文章
- 算法学习记录-图——最短路径之Dijkstra算法
在网图中,最短路径的概论: 两顶点之间经过的边上权值之和最少的路径,并且我们称路径上的第一个顶点是源点,最后一个顶点是终点. 维基百科上面的解释: 这个算法是通过为每个顶点 v 保留目前为止所找到的从 ...
- 算法与数据结构(六) 迪杰斯特拉算法的最短路径(Swift版)
上篇博客我们详细的介绍了两种经典的最小生成树的算法,本篇博客我们就来详细的讲一下最短路径的经典算法----迪杰斯特拉算法.首先我们先聊一下什么是最短路径,这个还是比较好理解的.比如我要从北京到济南,而 ...
- 数据结构与算法--最短路径之Bellman算法、SPFA算法
数据结构与算法--最短路径之Bellman算法.SPFA算法 除了Floyd算法,另外一个使用广泛且可以处理负权边的是Bellman-Ford算法. Bellman-Ford算法 假设某个图有V个顶点 ...
- 数据结构与算法--最短路径之Floyd算法
数据结构与算法--最短路径之Floyd算法 我们知道Dijkstra算法只能解决单源最短路径问题,且要求边上的权重都是非负的.有没有办法解决任意起点到任意顶点的最短路径问题呢?如果用Dijkstra算 ...
- 数据结构与算法--最短路径之Dijkstra算法
数据结构与算法--最短路径之Dijkstra算法 加权图中,我们很可能关心这样一个问题:从一个顶点到另一个顶点成本最小的路径.比如从成都到北京,途中还有好多城市,如何规划路线,能使总路程最小:或者我们 ...
- <数据结构>图的最短路径问题
目录 最短路径问题 Dijstra算法:中介点优化 基本步骤 伪代码 在实现过程中的关键问题 代码实现 邻接矩阵版 邻接表版 时间复杂度:O(VlogV+E) 算法存在的问题:存在负权边时会失效 Be ...
- 【算法设计与分析基础】25、单起点最短路径的dijkstra算法
首先看看这换个数据图 邻接矩阵 dijkstra算法的寻找最短路径的核心就是对于这个节点的数据结构的设计 1.节点中保存有已经加入最短路径的集合中到当前节点的最短路径的节点 2.从起点经过或者不经过 ...
- JavaScript数据结构——图的实现
在计算机科学中,图是一种网络结构的抽象模型,它是一组由边连接的顶点组成.一个图G = (V, E)由以下元素组成: V:一组顶点 E:一组边,连接V中的顶点 下图表示了一个图的结构: 在介绍如何用Ja ...
- 数据结构C语言版 弗洛伊德算法实现
/* 数据结构C语言版 弗洛伊德算法 P191 编译环境:Dev-C++ 4.9.9.2 */ #include <stdio.h>#include <limits.h> # ...
随机推荐
- HDU 3666 THE MATRIX PROBLEM (差分约束,最短路)
题意: 给一个n*m矩阵,每个格子上有一个数字a[i][j],给定L和U,问:是否有这样两个序列{a1...an}和{b1...bn},满足 L<=a[i][j]*ai/bj<=U .若存 ...
- App中嵌入网页浏览器
TOWebViewController 插件 NSURL *url =[NSURL URLWithString:@"http://192.168.1.134:8180/Home/IndexP ...
- 删除binlog的方法
不知道你有没有为mysql的binlog占用大量磁盘感到无奈,my.cnf里binlog的size可以设置多大做分割,但没有看到删除的配置,在mysql里show了一下variables, mysql ...
- Linux makefile教程之后序十一[转]
后序 —— 终 于到写结束语的时候了,以上基本上就是GNU make的Makefile的所有细节了.其它的产商的make基本上也就是这样的,无论什么样的make,都是以文件的依赖性为基础的,其基本是都 ...
- 堪称最好的A*算法
原文地址:http://theory.stanford.edu/~amitp/GameProgramming/ 相关链接:http://www-cs-students.stanford.edu/%7E ...
- the server responded with a status of 404 (Not Found)
1.出现这种问题,第一时间检查文件路径是否正确,相对路径或者绝对路径是否正确 2.某些后缀的文件是否能够找到,我现在碰到的就是.md文件找不到,需要配置web.config <system.we ...
- win8 VS控件信息
<TextBlock x:Name="button_1" HorizontalAlignment="Center" TextWrapping=" ...
- storm流式大数据处理流行吗
在如今这个信息高速增长的今天,信息实时计算处理能力已经是一项专业技能了,正是因为有了这些需求的存在才使得分布式,同时具备高容错的实时计算系统Storm才变得如此受欢迎,为什么这么说呢?下面看看新霸哥的 ...
- Hybrid App简介
Hybrid App 是混合模式应用的简称,兼具 Native App 和 Web App 两种模式应用的优势,开发成本低,拥有Web技术跨平台特性.目前大家所知道的基于中间件的移动开发框架都是采用的 ...
- RPC基础篇
RPC概念 RPC(Remote Procedure Call Protocol)——远程过程调用协议, 是一种进程间通信方式.它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数 ...