数据结构——图——最短路径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> # ...
随机推荐
- libserialport: cross-platform library for accessing serial ports
/*********************************************************************************** * libserialport ...
- 新浪微博顶部新评论提示层效果——position:fixed
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 【转】strcpy溢出的攻击示例
在学习c/c++的时候,就讲到了一些C类型的字符串函数不是安全的,比如strcpy没有检查长度会溢出,推荐使用strncpy,笔试面试也经常问到.同时经常浏览安全相关的新闻,缓冲区溢出攻击是很常见的一 ...
- 【解题报告】POJ-1467 Symbolic Derivation
原题地址:http://poj.org/problem?id=1467 题目大意: 对一个式子求导,给的式子包括常量,字母x,+,-,*,/,ln()运算符,任意嵌套的括号.求的导数式子不用化简,如1 ...
- Symfony2 学习笔记之插件格式
一个bundle类似于其它框架中的插件,但是比插件表现更好.它跟其它框架最主要的不同是在Symfony2中所有东西都是bundle,包括核心框架功能和你写的所有应用程序代码.Symfony2中,bun ...
- Spring3.0.6定时任务
项目使用的Spring版本比较旧是3.0.6版本,由于需要进行定时任务,就决定使用Spring自带的scheduled task. 在网上找了很多文章,也查看了Spring3.0.6的官方文档,按照网 ...
- webtest 文章
一直也没有和游戏类测试打过交道,看到“腾讯WeTest ”提供的测试服务,以及和手机游戏相关的技术文章.在此作个备份记录的. 手游专题 http://wetest.qq.com/lab/tag/?ta ...
- elasticsearch-head 的搭建
elasticsearch-head 全部是js和html5写的,elasticsearch 全部都是http的接口, 这样,只需要简单地本地配置一个虚拟站点,就可以搭建 elasticsearch ...
- js与C#服务端 json数据交互
1.1 服务端返回给前端 返回的数据都放入对象中(根据需求:单个对象,集合,键值对),然后JSON序列化返回给前端.这里可以引用JSON.NET 库,也可以用.NET自带的类库: JavaScript ...
- C++ 中类的构造函数理解(二)
C++ 中类的构造函数理解(二) 写在前面 上次的笔记中简要的探索了一下C++中类的构造函数的一些特性,这篇笔记将做进一步的探索.主要是复制构造函数的使用. 复制构造函数 复制构造函数也称拷贝构造函数 ...