【C语言—最短路径】迪杰斯特拉(dijkstra)算法和弗洛伊德(floyd)算法

网图及其邻接矩阵

在这里插入图片描述
求得从一个顶点出发到达另一个顶点的最短路径

迪杰斯特拉算法

实现步骤

1、从源点出发(V0),找到最近的一个顶点(V1)
2、比较以V1作为中间节点,V0到其他顶点的距离与V0直接到该顶点的距离的大小
3、从中选择更短的距离(V2)
4、重复2,3步骤,直至找到所有顶点与源点的最短路径

代码实现

/*
 * @Author: Xyh4ng
 * @Date: 2022-11-23 16:32:39
 * @LastEditors: Xyh4ng
 * @LastEditTime: 2022-11-23 18:23:11
 * @Description:
 * Copyright (c) 2022 by Xyh4ng 503177404@qq.com, All Rights Reserved.
 */
#include <stdio.h>
#include <stdlib.h>

#define INFINITY 500

typedef struct
{
    int vex[9];
    int (*edges)[9];
    int vexNums, edgeNums;
} MGraph;

void ShortestPath(MGraph *G, int v0, int patharc[], int shortPathTable[])
{
    int flag[9] = {0}; // 记录节点是否已经算得最短路径
    // 记录源点
    patharc[0] = v0;
    for (int i = 0; i < G->vexNums; i++)
    {
        shortPathTable[i] = G->edges[v0][i];
    }
    flag[v0] = 1;
    // 寻找最近的下一个顶点
    for (int i = 1; i < G->vexNums; i++)
    {
        int min = INFINITY;
        int k;
        for (int j = 0; j < G->vexNums; j++)
        {
            if (flag[j] != 1 && shortPathTable[j] < min)
            {
                min = shortPathTable[j];
                k = j;
            }
        }
        flag[k] = 1;
        // 更新最短路径
        for (int j = 0; j < G->vexNums; j++)
        {
            if (flag[j] != 1 && min + G->edges[k][j] < shortPathTable[j])
            {
                shortPathTable[j] = min + G->edges[k][j];
                patharc[j] = k;
            }
        }
    }
}

int main()
{
    int patharc[9] = {0};        // 记录最短路径的顶点(index)对应的前驱顶点(value)
    int shortPathTable[9] = {0}; // 记录源点到各个顶点(index)最短路径的权重和(value)

    MGraph *G = (MGraph *)malloc(sizeof(MGraph));
    G->vexNums = 9;
    G->edgeNums = 16;
    for (int i = 0; i < G->vexNums; i++)
    {
        G->vex[i] = i;
    }
    int edgeMatrix[9][9] = {
        {0, 1, 5, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY},
        {1, 0, 3, 7, 5, INFINITY, INFINITY, INFINITY, INFINITY},
        {5, 3, 0, INFINITY, 1, 7, INFINITY, INFINITY, INFINITY},
        {INFINITY, 7, INFINITY, 0, 2, INFINITY, 3, INFINITY, INFINITY},
        {INFINITY, 5, 1, 2, 0, 3, 6, 9, INFINITY},
        {INFINITY, INFINITY, 7, INFINITY, 3, 0, INFINITY, 5, INFINITY},
        {INFINITY, INFINITY, INFINITY, 3, 6, INFINITY, 0, 2, 7},
        {INFINITY, INFINITY, INFINITY, INFINITY, 9, 5, 2, 0, 4},
        {INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, 7, 4, 0}};
    G->edges = edgeMatrix;
    ShortestPath(G, 0, patharc, shortPathTable);
    // 求源点到终点的最短路径
    int i = 5;
    printf("%d", i);
    while (patharc[i] != 0)
    {
        printf("%d", patharc[i]);
        i = patharc[i];
    }
    printf("%d", patharc[0]);

    return 0;
}

弗洛伊德算法

实现步骤

(求所有顶点到其他顶点的最短路径)
在这里插入图片描述
在这里插入图片描述

代码实现

/*
 * @Author: Xyh4ng
 * @Date: 2022-11-23 16:32:39
 * @LastEditors: Xyh4ng
 * @LastEditTime: 2022-11-23 20:48:16
 * @Description:
 * Copyright (c) 2022 by Xyh4ng 503177404@qq.com, All Rights Reserved.
 */
#include <stdio.h>
#include <stdlib.h>

#define INFINITY 500

typedef struct
{
    int vex[9];
    int (*edges)[9];
    int vexNums, edgeNums;
} MGraph;

void ShortestPath(MGraph *G, int patharc[9][9], int shortPathTable[9][9])
{
    // 初始化
    for (int i = 0; i < G->vexNums; i++)
    {
        for (int j = 0; j < G->vexNums; j++)
        {
            shortPathTable[i][j] = G->edges[i][j];
            patharc[i][j] = j;
        }
    }
    // 算法开始
    for (int k = 0; k < G->vexNums; k++)
    {
        for (int i = 0; i < G->vexNums; i++)
        {
            for (int j = 0; j < G->vexNums; j++)
            {
                if (shortPathTable[i][k] + shortPathTable[k][j] < shortPathTable[i][j])
                {
                    shortPathTable[i][j] = shortPathTable[i][k] + shortPathTable[k][j];
                    patharc[i][j] = patharc[i][k];
                }
            }
        }
    }
}

int main()
{
    int patharc[9][9];        // 记录最短路径的顶点(index)对应的前驱顶点(value)
    int shortPathTable[9][9]; // 记录源点到各个顶点(index)最短路径的权重和(value)

    MGraph *G = (MGraph *)malloc(sizeof(MGraph));
    G->vexNums = 9;
    G->edgeNums = 16;
    for (int i = 0; i < G->vexNums; i++)
    {
        G->vex[i] = i;
    }
    int edgeMatrix[9][9] = {
        {0, 1, 5, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY},
        {1, 0, 3, 7, 5, INFINITY, INFINITY, INFINITY, INFINITY},
        {5, 3, 0, INFINITY, 1, 7, INFINITY, INFINITY, INFINITY},
        {INFINITY, 7, INFINITY, 0, 2, INFINITY, 3, INFINITY, INFINITY},
        {INFINITY, 5, 1, 2, 0, 3, 6, 9, INFINITY},
        {INFINITY, INFINITY, 7, INFINITY, 3, 0, INFINITY, 5, INFINITY},
        {INFINITY, INFINITY, INFINITY, 3, 6, INFINITY, 0, 2, 7},
        {INFINITY, INFINITY, INFINITY, INFINITY, 9, 5, 2, 0, 4},
        {INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, 7, 4, 0}};
    G->edges = edgeMatrix;
    ShortestPath(G, patharc, shortPathTable);
    // 求源点到终点的最短路径
    int start = 0;
    int stop = 8;
    printf("%d", start);
    while (patharc[start][stop] != stop)
    {
        printf("%d", patharc[start][stop]);
        start = patharc[start][stop];
    }
    printf("%d", stop);

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值