digsktra算法和Floyd算法

  1. 问题
    [描述算法问题,首选形式化方式(数学语言),其次才是非形式化方式(日常语言)]

  2. 解析
    [问题的理解和推导,可用电子版直接在此编写,也可用纸笔推导,拍照嵌入本文档]
    1、Floyd算法是从带权的邻接矩阵起始,假设求Vi-Vj的最短路径,如果Vi-Vj有路径,通过图G.arc[i][j] 来表示路径的长度,但是此时的路径并不一定就是最短的,在此我们考虑在路径上添加另一个顶点V 0 {V0}V0 ,此时我们比较(V i {Vi}Vi,V j {Vj}Vj),(V i {Vi}Vi, V 0 {V0}V0, V j {Vj}Vj )这两条路径那条更短,通过dis[][]来表示更短的那条路径,此时找到的最短路径的含义就是V i {Vi}Vi-V j {Vj}Vj 中间顶点序号不超过0的最短路径,那么下一次插入的中间顶点就应该是V 1 {V1}V1,此时比较的就是(V i , . . . , V 1 , . . . , V j {Vi,…,V1,…,Vj}Vi,…,V1,…,Vj) 和 (V i {Vi}Vi,V j {Vj}Vj) 那个最短,此时求得了$ {Vi}− -−{Vj}$ 中间顶点序号不超过1的最短路径,插入顶点重复依次累加,插入的顶点V 0 , V 1 , . . . , V n − 1 {V_{0},V_{1},…,V_{n-1}}V 0 ,V 1,…,V n−1迭代此过程,执行 n次此过程最终dis[][]表示求得任意两点之间的最短路径。
    2、Digsktra算法处处可见Prim算法的影子,大体上两者都是在寻找当前情况下的最短边,而不同之处在于,迪杰斯特拉算法做了路程的累加

  3. 设计
    [核心伪代码]
    1、void Floyd(Graph G){
    int dis[MAX_VEX][MAX_VEX], path[MAX_VEX][MAX_VEX];
    for(int i = 0; i < G.numvex; i++){
    for(int j = 0; j < G.numvex; j++){
    if(i != j) dis[i][j] = G.arc[i][j];
    else dis[i][j] = 0;
    path[i][j] = j;
    }
    }
    for(int k = 0; k < G.numvex; k++){
    for(int i = 0; i < G.numvex; i++){
    for(int j = 0; j < G.numvex; j++){
    if(dis[i][k] + dis[k][j] < dis[i][j]){
    dis[i][j] = dis[i][k] + dis[k][j];
    path[i][j] = path[i][k];
    }
    }
    }
    }
    2、void ShortestPath_Dijkstra(MGraph *G,VertexType start)
    {
    int i,j,num;
    int loc;
    int min;
    int dist[VertexMax];//最短路径长度数组
    int path[VertexMax];//最短路径数组
    int s[VertexMax];//代表集合S(1代表该顶点已处理,属于集合S;0代表该顶点未处理,不属于集合S,属于集合V-S)

    //1.初始化dist和path数组
    loc=LocateVex(G,start);//获取源点的下标位置
    for(i=0;ivexnum;i++)
    {
    dist[i]=G->AdjMatrix[loc][i];//初始化dist数组

    if(dist[i]!=MaxInt)//初始化path数组
    {
    	path[i]=loc;
    }
    else
    {
    	path[i]=-1;
    }	  
    

    }

    //2.初始化S数组(s数组:代表集合S,1代表该元素属于集合S(已处理的顶点),0该元素不属于集合S(未处理的顶点))
    for(i=0;ivexnum;i++)
    {
    s[i]=0;
    }
    s[loc]=1;//代表起始点(源点)以处理完毕
    num=1;

    //3.
    while(numvexnum)
    {
    min=FindMinDist(dist,s,G->vexnum);//在dist数组中查找其对应s[i]=0,即未处理的最小值元素
    s[min]=1;//将找到的最短边所对应的的顶点加入集合S

    for(i=0;i<G->vexnum;i++)//加入新的顶点后,更新dist和path数组 
    {
    	if((s[i]==0)&&(dist[i]>dist[min]+G->AdjMatrix[min][i]))//路径累加
    	{
    		dist[i]=dist[min]+G->AdjMatrix[min][i];
    		path[i]=min;
    	}
    }
    num++;	
    

    }
    }

  4. 分析
    [算法复杂度推导]

  5. 源码
    [github源码地址]
    https://github.com/zddhandsome/Algorithm/blob/main/floyd%E7%AE%97%E6%B3%95.cpp
    https://github.com/zddhandsome/Algorithm/blob/main/Dijsktra%E7%AE%97%E6%B3%95.cpp

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

dd不是弟弟

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

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

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

打赏作者

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

抵扣说明:

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

余额充值