dijkstra算法求最短路径
2016-10-27 18:39
176 查看
希望大家能看完prim算法后再来看这个算法,因为两者思路差不多。
先来看一下自定义的结构体
主程序
creategraph函数是从txt里读取矩阵的函数,我写在了prim算法的帖子里,大家可以去看一下,这里就不说了。
来看一下dikstra算法
dist数组的元素是V0节点到其他各点的路径。如果二维数组的graph->arcs[i][i]的值为0,说明此时Vi节点还没加入我们的判断范围,就是说我们求得最短路径里不能经过Vi节点,所以我们一开始默认V0节点加入判断范围,也就是说,我们求得路径就是V0节点到其他节点的最短路径,所以for循环是从1开始的。以为不用求V0到V0的最短路径
先初始化V0到其他各节点的距离,这些距离是从txt里存储的矩阵中读取的。如果两个节点之间没有路径,就默认路径距离为1000.路径前驱节点为-1.
1.初始化完成后,进行fo循环来寻找最短路径。先找一条最短路径(当前数组元素里length最小的).if((graph->arcs[j][j]==0)&&(dist[j].length
这里其实就是把数组元素的一些成员打印出来。数组下标i就代表V0到Vi的最短路径.
需要说明两点.
1.上面已经提到了,如果路径长度等于MAX(1000)。说明两个节点之间没有路径。
2.我们找的最短路径是V0到其他节点的最短路径。如果第i条路径的前驱节点不是V0,假设为Vj,说明V0到这个节点的最短路径是经过其他节点的。这个时候我们还要找第J条路径,就这样往前找,知道前驱节点为V0.
最后看一下运行截图
先来看一下自定义的结构体
typedef char VexType; typedef int AdjType; typedef struct{ int n; VexType vexs[MaxNode];//保存节点 AdjType arcs[MaxNode][MaxNode];//从矩阵获得节点与节点间的距离 }GraphMatrix; typedef struct{ AdjType length;//边长 int prevex;//先驱节点 }path;
主程序
void main() { GraphMatrix *mygraph; path *mydist; // Edge *mymst; mygraph = (GraphMatrix*)malloc(sizeof(GraphMatrix)); //mymst = (Edge*)malloc(sizeof(Edge)); mydist = (path*)malloc(sizeof(path)); CreateGraph(mygraph,6); printf("testing creategraph\n"); dijkstra(mygraph,mydist); printf("testing dijkstra:\n"); print_path(mygraph,mydist); }
creategraph函数是从txt里读取矩阵的函数,我写在了prim算法的帖子里,大家可以去看一下,这里就不说了。
来看一下dikstra算法
void dijkstra(GraphMatrix *graph,path *dist) { int i,j,min; AdjType minw; dist[0].length = 0; dist[0].prevex = 0; graph->arcs[0][0] = 1;//表示v0加入集合 for(i=1;i<graph->n;i++)//从V1节点开始 { dist[i].length = graph->arcs[0][i];//初始化v0到各个节点的距离 if(dist[i].length!=Max) { dist[i].prevex = 0;//不等于Max说明V0可以到Vi节点 } else { dist[i].prevex = -1;//V0到Vi没有路径 } } for(i=1;i<graph->n;i++)//一次循环就会找到V0到其中一个顶点的最短距离,所以循环节点数-1次 { minw = Max; min = 0; for(j=1;j<graph->n;j++) { if((graph->arcs[j][j]==0)&&(dist[j].length<minw))//==0说明节点j还未加入 { minw = dist[j].length; min = j; } } if(min==0)//如果都不等于0,说明所有节点都已加入,也就是已经调整好了,如果都大于minw说明所有路径已经达到最短 { break; } graph->arcs[min][min]=1;//将顶点为min的顶点加入集合,此时V0到Vmin的节点的最短距离已经找到,下面 b431 进行调整时就是判断通过Vmin点再到其他点距离是否会减少 for(j=1;j<graph->n;j++) { if(graph->arcs[j][j]==1) { continue;//V0到节点Vi的最短路径已经找到,不在进行调整 } if(dist[j].length>dist[min].length+graph->arcs[min][j])//V0到Vmin的距离+Vmin到Vj的距离 { dist[j].length = dist[min].length+graph->arcs[min][j];//变更路径长度 dist[j].prevex = min;//V0到Vj的先驱节点从V0变更成Vmin } } } }
dist数组的元素是V0节点到其他各点的路径。如果二维数组的graph->arcs[i][i]的值为0,说明此时Vi节点还没加入我们的判断范围,就是说我们求得最短路径里不能经过Vi节点,所以我们一开始默认V0节点加入判断范围,也就是说,我们求得路径就是V0节点到其他节点的最短路径,所以for循环是从1开始的。以为不用求V0到V0的最短路径
先初始化V0到其他各节点的距离,这些距离是从txt里存储的矩阵中读取的。如果两个节点之间没有路径,就默认路径距离为1000.路径前驱节点为-1.
1.初始化完成后,进行fo循环来寻找最短路径。先找一条最短路径(当前数组元素里length最小的).if((graph->arcs[j][j]==0)&&(dist[j].length
void print_path(GraphMatrix* graph, path* dist) { int i,j; for(i=1;i<graph->n;i++) { j = i; if(dist[i].length==Max) { printf("V0到V%d没有路径\n",i);//设定床为MAX说明没有路径 } else { printf("V%d到V0的路径为: %d ",i,i); while(dist[j].prevex!=0)//Vj的前驱节点不是V0说明经过其他节点Vx,V0到Vx的路径中的前驱节点为dist[j].prevex,循环验证 { printf("%d ",dist[j].prevex); j = dist[j].prevex; } printf("0"); printf("\nV%d到V0的路径长度为%d\n",i,dist[i].length); printf("\n\n"); } } }
这里其实就是把数组元素的一些成员打印出来。数组下标i就代表V0到Vi的最短路径.
需要说明两点.
1.上面已经提到了,如果路径长度等于MAX(1000)。说明两个节点之间没有路径。
2.我们找的最短路径是V0到其他节点的最短路径。如果第i条路径的前驱节点不是V0,假设为Vj,说明V0到这个节点的最短路径是经过其他节点的。这个时候我们还要找第J条路径,就这样往前找,知道前驱节点为V0.
最后看一下运行截图
相关文章推荐
- 最短路径--Dijkstra算法
- 最短路径:Dijkstra算法和Floyd算法
- 最短路径—Dijkstra算法和Floyd算法
- 算法设计与分析——使用dijkstra算法计算最短路径并且给出路径上的节点序列
- 算法学习(1):最短路径—Dijkstra算法和Floyd算法
- 最短路径—Dijkstra算法和Floyd算法
- 利用Dijkstra算法实现记录每个结点的所有最短路径
- 最短路径问题——Dijkstra算法(C++实现)
- HDU3790 最短路径问题【Dijkstra算法】
- Dijkstra算法求图的单源最短路径
- 最短路径—Dijkstra算法和Floyd算法
- 最短路径问题---Dijkstra算法详解
- Dijkstra算法(一个节点到其他所有节点的最短路径)
- 用java编写的一个迪杰斯特拉算法(单源最短路径算法,Dijkstra算法)。
- Dijkstra算法(单源最短路径) C++
- 用Python实现Dijkstra算法用来寻找两点之间的最短路径 (Implementation of Dijkstra in Python)
- 有向图最短路径问题---Dijkstra算法(过程)
- Java用Dijkstra算法实现地图两点的最短路径查询(Android版)
- 最短路径之Dijkstra算法详细讲解
- dijkstra算法求两点之间最短路径