数据结构笔记13-最短路径

在非网图中,最短路径是指两顶点之间经历的边数最少的路径。 
在网图中,最短路径是指两顶点之间经历的边上权值之和最短的路径。

Dijkstra算法
基本思想:
1、设置一个集合S存放已经找到最短路径的顶点,S的初始状态只包含源点v,
2、对vi∈V-S,假设从源点v到vi的有向边为最短路径(从v到其余顶点的最短路径的初
值)。
3、以后每求得一条最短路径v, …, vk,就将vk加入集合S中,并将路径v, …, vk , vi与
原来的假设相比较,取路径长度较小者为最短路径。
4、重复上述过程,直到集合V中全部顶点加入到集合S中。

路径长度最短的最短路径(即第一条最短路)的特点:
    在这条路径上,必定只含一条边,并且这条边上的权值最小。
下一条路径长度次短的最短路径的特点:
    它只可能有两种情况:
    或者是直接从源点到该点(只含一条边); 
    或者是从源点经过顶点v1(第一条最短路径所依附的顶点),再到达该顶点(由两条
    边组成)。
再下一条路径长度次短的最短路径的特点:
    它可能有四种情况:或者是直接从源点到该点(只含一条边); 或者从源点经过顶点
    v1,再到达该顶点(由两条边组成);或者是从源点经过顶点v2,再到达该顶点(两
    条条边);或者是从源点经过顶点v1、v2,再到达该顶点(多条边)。
其余最短路径的特点:
    它或者是直接从源点到该点(只含一条边); 或者是从源点经过已求得最短路径的
    顶点(集合S中的顶点),再到达该顶点。
    
数据结构 :
图的存储结构:邻接矩阵存储结构
数组dist[n]:每个分量dist[i]表示当前所找到的从始点v到终点vi的最短路径的长
度。初态为:
    若从v到vi有弧,则dist[i]为弧上权值;否则置dist[i]为∞。
数组path[n]:path[i]是一个字符串,表示当前所找到的从始点v到终点vi的最短路
径。初态为:若从v到vi有弧,则path[i]为vvi;否则置path[i]空串。
数组s[n]:存放源点和已经找到最短路径的终点,其初态为只有一个源点v。 

const int MAX=1000;
void  Dijkstra(MGraph g, int v){
       for ( i =0; i<g.vexnum ; i++){
     dist[i]=g.arcs[v][i];  
               if ( dist[i]!= MAX) 
                      path [i]=g.vertex[v]+g.vertex[i];
               else
                      path[i]=“”;
       }
       S[0]=g.vertex[v]; 
       num=1;  
       While (num<g.vextexNum){
    k=0;
    for(i=0;i<G.vertexNum;i++)
           if((dist[i]<dist[k])   k=i
    cout<<dist[k]<<path[k];
    s[num++]=G.vertex[k];                
    for(i=0;i<G.vertexNum;i++)
             if(dist[k]+g.arc[k][i]<dist[i] {
         dist[i]=dist[k]+g.arc[k][i];
                       path[i]=path[k]+g.vertex[i];
               }
}
}


Floyd算法
基本思想如下:
设图g用邻接矩阵法表示, 
    求图g中任意一对顶点vi、 vj间的最短路径。
    将vi到vj 的最短的路径长度初始化为(vi,vj), 然后进行如下n次比较
    和修正:
    在vi、vj间加入顶点v0,比较(vi, v0, vj)和(vi, vj)的路径的长度,
    取其中较短的路径作为vi到vj的且中间顶点号不大于0的最短路径。
    在vi、vj间加入顶点v1,
      得(vi, …,v1)和(v1, …,vj),其中:
     (vi, …, v1)是vi到v1 的且中间顶点号不大于0的最短路径,
        (v1, …, vj) 是v1到vj 的且中间顶点号不大于0的最短路径,
     这两条路径在上一步中已求出。 
      将(vi, …, v1, …, vj)与上一步已求出的且vi到vj 中间顶点号不大于0的最
      短路径比较,取其中较短的路径作为vi到vj 的且中间顶点号不大于1的最短路
      径。 
      在vi、vj间加入顶点v2,得
         (vi, …, v2)和(v2, …, vj), 其中:
         (vi, …, v2)是vi到v2 的且中间顶点号不大于1的最短路径,
          (v2, …, vj) 是v2到vj 的且中间顶点号不大于1的最短路径,
          这两条路径在上一步中已求出。
          将(vi, …, v2, …, vj)与上一步已求出的且vi到vj 中间顶点号不大于
          1的最短路径比较, 取其中较短的路径作为vi到vj 的且中间顶点号不大
          于2的最短路径。

图的存储结构:带权的邻接矩阵存储结构  
数组dist[n][n]:存放在迭代过程中求得的最短路径长度。迭代公式: 
dist-1[i][j]=edge[i][j]
dist k[i][j]=min{disk-1[i][j],disk-1[i][k]+disk-1[k][j]}
0≤k≤n-1
数组path[n][n]:
    存放从vi到vj的最短路径,初始为path[i][j]="vivj"。

    
void Floyd(MGraph G)
{
    for (i=0; i<G.vertexNum; i++)        
       for (j=0; j<G.vertexNum; j++)
       {
          dist[i][j]=G.arc[i][j];
          if (dist[i][j]!=∞) 
               path[i][j]=G.vertex[i]+G.vertex[j];
          else path[i][j]=""; 
       }
       for (k=0; k<G.vertexNum; k++)         
        for (i=0; i<G.vertexNum; i++)       
           for (j=0; j<G.vertexNum; j++)
               if (dist[i][k]+dist[k][j]<dist[i][j]) {
                    dist[i][j]=dist[i][k]+dist[k][j];
                    path[i][j]=path[i][k]+path[k][j];
              }
}

    
    

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十只兔子OVO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值