首页 > 其他 > 详细

数据结构(最短路径)

时间:2020-05-10 21:00:21      阅读:54      评论:0      收藏:0      [点我收藏+]

最短路径

  在网图和非网图中,最短路径的含义是不同的:

  • 网图是两顶点经过的边上的权之和最小的路径
  • 非网图是两顶点之间经过的边数最少的路径
  • 把路径起始的第一个顶点称为源点。最后一个顶点称为终点

  主要的方法有两种:

  • 迪杰斯特拉算法:求顶点到所有顶点的最短路径。O(n²)
  • 弗洛伊德算法:求所有顶点到所有顶点的最短路径。O(n³)

迪杰斯特拉算法

算法思路:

  一步步求与每个顶点的最短路径,过程中都是基于已经求出的最段路径的基础上,求得更远顶点的最段路泾,最终得到想要顶点的最段路径(其实与普利姆算法是非常相似的)

方法:

  • 用3个数组:final数组,ShortPathTable数组,Patharc数组
  • final数组:标记顶点是否已求出最短路径(0/1)
  • ShortPathTable数组:存储当前进度源点到各顶点的最短距离
  • Patharc数组:存储当前对应位置当前ShortPathTable数组距离路径的前驱

技术分享图片

 1 #define MAXVEX 9//宏定义图的最大定点数
 2 #define INFINITY 65535//路不通时的默认值
 3 
 4 typedef int Patharc[MAXVEX]//用于存储最段路经下标的数据
 5 typedef int ShortPathTable[MaxVEX]//用于存储到各点的最短路径的权值和
 6 
 7 //G:图结构:are,矩阵二维数组;numVertexes,图中顶点数
 8 //A:用于传入源点
 9 //P就是Patharc数组,用于存储源点到下标位置对应顶点为终点的最短路径的倒数第二个顶点的下标(最段路经终点的前驱)
10 //D就是ShortPathTable数组,用于存储各源点A到其他各点的最短路径权之和
11 void ShortestPath_Dijkstar(MGraph G,int A,patharc *P,ShortPathTable *D){
12     int v,w,k,min;
13     int final[MAXVEX];//标记数组:用于标志是否已经找到源点到对定位置的最段路经【0表示未找到,1表示已经找到】
14     
15     //初始化数据
16     for(v=0;v<G.numVertexes;v++){
17         final[v]=0;//全部顶点初始化为未找到最段路泾
18         (*D)[v]=G.are[A][v];//因为寻找A下标顶点到各顶点的最短路径,所以初始化时就是为矩阵中第v行的数据(这行数据就是这个顶点到各顶点的权)
19         (*P)[v]=0;//初始化路径数组为0
20     }
21     (*D)[A]=0;//源点到源点的路径权为0
22     final[A]=1;//源点到源点的路径已经找到
23 
24     //开始循环,找源点到其他[G.numVertexes-1]个顶点的最短路径
25     for(v=1;v<G.numVertexes;v++){//【循环1】:循环一次找到一个源点到其他点【X】的最短路径
26         min=INFINITY;
27         for(w=0;w<G.numVertexes;w++){
28             if(!final[w] && (*D)[w]<min){//在未找到最短路径的顶点中找当前距离源点权最近的那个顶点,这个顶点就是【循环1】本次循环所找到的【X】
29                 k=w;//记录这次找到最短路径的终点下标
30                 min=(*D)[w];//记录这次找到点的最短路径的权(这里的权就是这条路径的权之和)
31             }
32         }
33         final[k]=1;//标记源点到该顶点为终点的最短路径已经找
34 
35         //修正当点进度源点到各点的最短距离;因为为源点多加了一条边,就为源点到各点添加了若干条路,这些路会有刷新源点到其他点的最短距离
36         for(w=0;w<G.numVertexes;w++){
37             //未找最短路径到的顶点【Y】中;从源点到【X】再到【Y】的距离小于原先距离,就刷新了原先到【Y】的距离
38             if(!final[w] && (min+G.arc[k][w] < (*D)[w])){
39                 (*D)[w]=min+G.arc[k][w];//刷新该距离
40                 (*P)[w]=k;//记录刷新到w顶点的最短距离的顶点,也是这条当前最短距离路径的前驱
41             }
42         }
43     }
44 }

弗洛伊德算法

  求是是所有顶点到所有顶点的距离;O(n³)

算法思路:

  判断两顶点之间依次经过任意中间点是否会减短原先路径,可以的话就在路径上添加这个中间点,判断过全部中间点后就得到了所有能减短路径的中间点,那么两点和这些有效的中间点之间的路径就都成了短路径;

查找最短路径:

  查找时则是在Pathmatirx数组中查看是否存在中间点(-1代表没有中间点);若有中间点则递归查找源点到中间点的最短距离中间点到终点的最短路径,没有中间点就表示源点直接到终点就是最短路径,打印这条路径,返回即可;

方法:

  • 定义中间点
  • 刚开始定义中间点位0,那么就判断全部顶点中任意两顶点,源点通过0再走向终点的距离是够小于源点直接走向终点的距离
  • 小于的话,那么就在Pathmatirx数组中Pathmatirx【源点下标】【终点下标】位置修改为中间点下标的位置;否则不做处理
  • 循环①,③,③步骤,让中间点从0~【G.numVertexes-1】循环过去即可

技术分享图片

 1 #define MAXVEX 9//宏定义图的最大定点数
 2 #define INFINITY 65535//路不通时的默认值
 3 
 4 typedef int Pathmatirx[MAXVEX][MAXVEX]//用于存储最段路经下标的数据
 5 typedef int ShortPathTable[MaxVEX][MaxVEX]//用于存储到各点的最短路径的权值和
 6 
 7 void ShortesPath_Floyd(MGraph G,Pathmatirx *D,ShortPathTable *D){
 8     int v,w,k;
 9     //初始化D和P
10     for(v=0;V<G.numVertexes;v++){
11         for(w=0;w<G.numVertexes;w++){
12             (*D)[v][w]=G.matirx[v][w];
13             (*P)[v][w]=w;
14         }
15     }
16 
17     //弗洛伊德算法
18     for(k=0;k<G.numVertexes;k++){
19         for(v=0;v<G.numVertexes;v++){
20             for(w=0;w<G.numVertexes;w++){
21                 if( (*D)[v][w] > (*D)[v][w] + (*D)[k][w] ){
22                     (*D)[v][w]=(*D)[v][w]+(*D)[k][w];
23                     (*P)[v][w]=(*P)[v][k];
24                 }
25             }
26         }
27     }
28 }
29 
30 void printPath(MGraph G,int u,int v,int Pathmatirx[][MAXVEX]){
31     int mid;
32     if(Pathmatirx[u][v]==-1)
33         printf("<%c,%c>  ",G.lin[u],G.lin[v]);
34     else{
35         mid= Pathmatirx[u][v];
36         printPath(G,u,mid,Pathmatirx);
37         printPath(G,mid,v,Pathmatirx);
38     }
39 }

 

数据结构(最短路径)

原文:https://www.cnblogs.com/TianLiang-2000/p/12864650.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!