最短路径之floyd算法c语言实现

本文介绍了图论中的弗洛伊德算法,用于求解所有顶点对之间的最短路径。通过使用三重循环遍历邻接矩阵,动态更新最短路径。并提供了一个C++实现的示例,包括创建无向网的邻接矩阵及最短路径计算。该算法具有简洁和高效的特点,时间复杂度为O(n^3)。

最短路径之floyd算法

简介

原理:用数组的形式存放每对顶点的最短路径长度。
辅助向量:
D[][]用来存放带权长度。
P[][]用来存放前驱顶点

一个测试用例

在这里插入图片描述

核心代码

 for(k=0;k<G.numVertexes;k++)
    {
        for(v=0;v<G.numVertexes;v++)
        {
            for(w=0;w<G.numVertexes;w++)
            {
                if((*D)[v][w] > (*D)[v][k]+(*D)[k][w])
                {
                    (*D)[v][w]=(*D)[v][k]+(*D)[k][w];
                    (*P)[v][w]=(*P)[v][k];
                }
            }
        }
    }

源代码


/************************
*最短路径之floyd
*时间复杂度:O(n^3)
*优点:形式简单,算法优美。核心代码,三个for循环。
*D[][]用来存放带权长度。
*P[][]用来存放前驱顶点
******************************************************/

#include<stdio.h>
#include<stdlib.h>
#define MAXVER 50 //最大顶点数
#define INFINITY 65535 //65535表示无穷大(邻接表中 权为无穷大表示没有弧)

typedef	int	Patharc[MAXVER][MAXVER];			// 用于存储最短路径下标的数组
typedef int	ShortPathTable[MAXVER][MAXVER];		// 用于存储到各点最短路径的权值和

typedef struct  MGraph
{
    char vertex[MAXVER] ;  //顶点表
    int arc[MAXVER][MAXVER] ;//邻接矩阵
	int numVertexes, numEdges;//图中当前顶点数和边数
}MGraph;

//建立无向网的邻接矩阵
void  CreateGraph(MGraph *G)
{
	int i, j,k,w;
	//设置顶点个数
	printf("请输入图的顶点数,边数:\n");
	scanf("%d %d", &G->numVertexes, &G->numEdges);
	//getchar();//清空缓冲区(主要是回车)
	setbuf(stdin, NULL);//设置输入缓冲区 为空缓冲区
	
	//设置结点存储值
	for (i = 0; i < G->numVertexes; i++)
	{
		printf("\n请输入第%d个顶点存储的值:",i);
		scanf("%c", &G->vertex[i]);

		// printf("%c",G->vertex[i]);

		setbuf(stdin, NULL);//设置输入缓冲区 为空缓冲区(每次输入一个回车,这里会造成 \n字符存在缓冲区)
	}
	for (i = 0; i < G->numVertexes; i++)
	{
		for (j = 0; j < G->numVertexes; j++)
		{ 
            if(i == j)
            {
                G->arc[i][j] = 0;
            }
            else
            {
               G->arc[i][j] = INFINITY;//初始化邻接矩阵(权为INFINITY无穷大表示没有弧)
            }	
		}
	}
	for (k = 0; k < G->numEdges; k++)
	{
		printf("请输入边(vi,vj)的下标i,下标j对应的权w:");
		scanf("%d %d %d", &i, &j, &w);
		G->arc[i][j] = w;//设置对应的权
		G->arc[j][i] = G->arc[i][j];//无向网,对称矩阵
	}
}

void ShortestPath_Floyd(MGraph G,Patharc *P,ShortPathTable *D)
{
    int v,w,k;//v:行。w:列。k:一次变换。

    //初始化D和P
    for (v=0;v<G.numVertexes;v++)
    {
        for(w=0;w<G.numVertexes;w++)
        {
            (*D)[v][w] = G.arc[v][w];
            (*P)[v][w] = w;
        }
    }

    //优美的floyd算法
    for(k=0;k<G.numVertexes;k++)
    {
        for(v=0;v<G.numVertexes;v++)
        {
            for(w=0;w<G.numVertexes;w++)
            {
                if((*D)[v][w] > (*D)[v][k]+(*D)[k][w])
                {
                    (*D)[v][w]=(*D)[v][k]+(*D)[k][w];
                    (*P)[v][w]=(*P)[v][k];
                }
            }
        }
    }
}


int main()
{
    int v,w;
    MGraph G;
    CreateGraph(&G);
    Patharc P;
    ShortPathTable D;

    ShortestPath_Floyd(G,&P,&D);

    //循环读出D元素
    printf("D数组元素为:\n");
    for(v=0;v<G.numVertexes;v++)
    {
        for(w=0;w<G.numVertexes;w++)
        {
            printf("%d ",D[v][w]);
        }
        printf("\n");
    }

    //循环读出P元素
     printf("P数组元素为:\n");
    for(v=0;v<G.numVertexes;v++)
    {
        for(w=0;w<G.numVertexes;w++)
        {
            printf("%d ",P[v][w]);
        }
        printf("\n");
    }

    system("pause");
    return 0;
}

测试结果

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值