数据结构C语言实现Floyed算法求最短路

本文记录了一次数据结构作业,使用Floyd算法求解有向图中每对顶点间的最短路径。通过邻接矩阵表示图,详细解释了算法步骤,包括初始化矩阵D和迭代更新最短路径。最后展示了在CodeBlocks上运行的程序结果。

作业记录之Floyed

其实是个数据结构作业啦!干脆写在这里,加深印象(干脆之后就不复习了吧(不
妈妈这人怎么这么懒呀
为什么老师布置作业要用Floyed算法…因为好理解吗…?
之后也把作业搬运过来,顺便复习了orz

介绍一下Floyed

Floyed算法使用带权的邻接矩阵来表示有向网,求从顶点u到v的最短距离。
自己理解的是
1)先定义一个n阶方阵D,D里面存放的是:从两点间单边路径的权(即中间不经过其他点),如果两点之间没有边相连,则权为无穷大(自己到自己是0)。
2)对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比已知的路径更短。如果是的话,就更新更新矩阵D。在这个过程中,不断开放顶点,不断迭代。如此,则D中就包含了最短通路径的信息。

时间复杂度:O(n^3)
空间复杂度:O(n^2)

示例翻课本(。

用Floyd算法求每对顶点间的最短路

描述:求出图的每队顶点的最短路
在这里插入图片描述
因为老师主要检验有向图,所以写的程序是有向图的邻接矩阵。如果是无向图,稍加修改就好了~

Path[i][j]:最短路径上顶点v的前一顶点的序号。
D[i][j]:记录顶点u和v之间的最短路径长度。

下面贴代码和结果:
(在CodeBlocks上运行的)

#include<stdio.h>
#include<stdlib.h>
#define MaxInt 32767 //极大值即"∞"
#define MVNum 100 //最大顶点数


//图的邻接矩阵存储
typedef struct{
    int arcs[MVNum][MVNum]; //边的权信息的数组
    int vexnum; //顶点数
    int arcnum; //边数
}AMGraph;

void CreateGraph(AMGraph &G) //创建图
{
    int v1,v2,w,i,j;
    printf("请输入图的顶点数:");
    scanf("%d",&G.vexnum);
    printf("请输入图的边数:");
    scanf("%d",&G.arcnum);
    printf("\n");
    for(i=0;i<G.vexnum;i++) //图的初始化
        for(j=0;j<G.vexnum;j++)
            {
            if(i==j)
                G.arcs[i][j]=0;
            else
                G.arcs[i][j]=MaxInt;
            }
    printf("\n");

    for(i=0;i<G.arcnum;i++)
    {
        printf("请输入边的信息(如1 2 3,前两个为顶点,第三个权):");  
        scanf("%d%d%d",&v1,&v2,&w);
        G.arcs[v1-1][v2-1]=w;
    }
}


void printGraph(AMGraph &G) //输出邻接矩阵的信息
{
    int i,j;
    printf("\n输出邻接矩阵:\n");
    for(i=0;i<G.vexnum;i++)
    {
        for(j=0;j<G.vexnum;j++)
        {
        if(G.arcs[i][j]==MaxInt)
            printf("%8s", "∞");
        else
            printf("%8d",G.arcs[i][j]);
        }
        printf("\n");
    }
}

void ShortestPath_Floyed(AMGraph G)
{//用Foyed算法求有向网G中各对顶点i和j之间的最短路径
    int i,j,k;
    int D[MVNum][MVNum];    //最短路径长度矩阵
    int Path[MVNum][MVNum];    //每一对顶点之间的最短路径

    for(i = 0;i < G.vexnum;++i)     //各对顶点之间初始已知路径及距离
        for(j = 0;j < G.vexnum;++j)
    {
        D[i][j] = G.arcs[i][j];
        if((D[i][j] < MaxInt) && (i!=j))
            Path[i][j] = i;    //如果i和j之间有弧,则将j的前驱置为i,否则为-1
        else Path[i][j] = -1;
    }

    for(k = 0;k < G.vexnum;++k)
    {
        for(i = 0;i < G.vexnum;++i)
        {
            for(j = 0;j < G.vexnum;++j)
            {
                if((D[i][k] + D[k][j]) < D[i][j])      //如果从i经K到j的一条路径更短,那么就更新D矩阵
                {
                    D[i][j] = D[i][k] + D[k][j];
                    Path[i][j] = Path[k][j];       //更改j的前驱为k
                }

            }
        }
    }
//接下来输出Floyed算法求得的结果
   printf("\n输出Floyed算法求得的结果:\n");
   for(i=0;i<G.vexnum;i++)
    {
        for(j=0;j<G.vexnum;j++)
        {
        if(D[i][j]==MaxInt)
            printf("%8s", "∞");
        else
            printf("%8d",D[i][j]);
        }
        printf("\n");
    }

}


int main()
{
    AMGraph G;
    CreateGraph(G);
    printGraph(G);
    ShortestPath_Floyed(G);
}

作业结果:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值