Floyd算法思想及实现

  Floyd算法用于求每一对顶点间的最短距离。与Dijkstra算法相比较,时间复杂度均为O(n2),但Floyd算法形式上更简单一些。

一、 Floyd算法的原理

首先记录两点间无其他中间顶点的距离(Vi---Vj),加一个顶点为中间点,记录加一个顶点后两点间的最短距离,以此类推,加完N个顶点后两点间的最短距离即可求出。

二、算法实现

  用三重循环实现。用二维数组表示顶点到顶点的距离。如D[i][j]表示从ij点的距离。第一层循环依次加顶点,第二层循环遍历Vi点,第三层循环遍历Vj点。

/*graph.h文件*/

//---------图的数组(邻接矩阵)存储表示----------

#include<stdio.h>

#include <string.h>

#include <stdlib.h>

#define INFINITY  10000        //最大值

#define MAX_VERTEX_NUM 20        //最大顶点个数  

typedef int VRType;        

typedef char VertexType;    

typedef char InfoType;       

typedef enum{DG,DN,UDG,UDN}  GraphKind; //有向图,有向网,无向图,无向网

typedef struct ArcCell

{

    VRType adj;                            //顶点关系类型,对无权图,有1或0表示是否相邻;对带权图,则为权值类型。

    InfoType *info;                        //弧相关信息的指针

}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];



typedef struct

{

    VertexType vexs[MAX_VERTEX_NUM];       //顶点向量

    AdjMatrix  arcs;                       //邻接矩阵

    int        vexnum,arcnum;              //图的当前顶点数和弧数

}mgraph,*MGraph;



int Locate_vexs(MGraph &g,VertexType v)        //定位顶点位置

{

    for (int i=0;i<g->vexnum;i++)

        if (g->vexs[i]==v)

            return i;

    return -1;

}



void Print_mgraph(MGraph &g)        //打印图

{    

    int i;

    printf("邻接矩阵为:\n");

    printf("");    //五个空格

    for (i=0;i<g->vexnum;i++)

        printf("%c     ",g->vexs[i]);

    printf("\n\n");

    for (i=0;i<g->vexnum;i++)

    {

        printf("%c     ",g->vexs[i]);

        for (int j=0;j<g->vexnum;j++)

        {

            //输出矩阵,并且调整矩阵

            if (g->arcs[i][j].adj>0&&g->arcs[i][j].adj<10)

                printf("%d     ",g->arcs[i][j].adj);

            else if (g->arcs[i][j].adj>9&&g->arcs[i][j].adj<100)

                printf("%d    ",g->arcs[i][j].adj);

            else if (g->arcs[i][j].adj>99&&g->arcs[i][j].adj<1000)

                printf("%d   ",g->arcs[i][j].adj);

            else if (g->arcs[i][j].adj>999&&g->arcs[i][j].adj<10000)

                printf("%d  ",g->arcs[i][j].adj);

            else if(g->arcs[i][j].adj==INFINITY)

                printf("");

        }

        printf("\n\n");

    }    

}



void Add_vexs(MGraph &g)            //增加顶点

{

    printf("请输入顶点个数:");

    scanf("%d",&g->vexnum);

    getchar();//吸收回车符

    printf("请输入顶点字符串序列:");

    for (int i=0;i<g->vexnum;i++)

        scanf("%c",&g->vexs[i]);

}



void Add_arcs(MGraph &g)            //增加边

{

    printf("请输入边的条数:");

    scanf("%d",&g->arcnum);

    VertexType v1,v2;

    int row,col;

    VRType weight;;

    printf("请输入权重和对应顶点,以空格隔开:\n");

    for (int i=0;i<g->arcnum;i++)

    {

        scanf("%d %c %c",&weight,&v1,&v2);

        row=Locate_vexs(g,v1);

        col=Locate_vexs(g,v2);

        g->arcs[row][col].adj=weight;

        

    }

}



void Init_graph(MGraph &g)            //初始化图

{

    g=(MGraph)malloc(sizeof(mgraph));

    g->vexnum=0;

    g->arcnum=0;

    for (int i=0;i<MAX_VERTEX_NUM;i++)

        g->vexs[i]='0';

    for (i=0;i<MAX_VERTEX_NUM;i++)

        for (int j=0;j<MAX_VERTEX_NUM;j++)

        {

            g->arcs[i][j].adj=INFINITY;

            g->arcs[i][j].info=NULL;

        }

}



void Create_mgraph(MGraph &g)        //创建图

{

    Add_vexs(g);

    Add_arcs(g);

}
/*Floyd.cpp文件*/

#include "graph.h"

#define FALSE 0

#define TRUE 1

typedef int DistancMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];        //存放路径长度

typedef int PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM][MAX_VERTEX_NUM];    

//存放路径,P[0][1][]表示顶点0到顶点1的路径,经过哪个点P[0][1][i]就是TRUE。



void Print_DistancMatrix(MGraph g,DistancMatrix &D)        //打印距离矩阵

{

    int i;

    printf("\t\t距离矩阵为:\n");

    printf("");    //五个空格

    for (i=0;i<g->vexnum;i++)

    {

        printf("%c     ",g->vexs[i]);

    }

    printf("\n\n");

    for (i=0;i<g->vexnum;i++)

    {    

        printf("%c     ",g->vexs[i]);

        for (int j=0;j<g->vexnum;j++)

        {

            if (D[i][j]>0&&D[i][j]<10)

                printf("%d     ",D[i][j]);

            else if (D[i][j]>9&&D[i][j]<100)

                printf("%d    ",D[i][j]);    

            else if (D[i][j]>99&&D[i][j]<1000)

                printf("%d   ",D[i][j]);    

            else if (D[i][j]>999&&D[i][j]<10000)

                printf("%d  ",D[i][j]);    

            else if(D[i][j]==INFINITY)

                printf("");

        }

        printf("\n\n");

    }

    printf("-----------------------------------------\n");

}



void Print_PathMatrix(MGraph g,PathMatrix &P)

{

    int i;

    printf("\t\t最短路径矩阵为:\n");

    for (i=0;i<g->vexnum;i++)

    {

        printf("#######");

        for (int vexcount=0;vexcount<g->vexnum;vexcount++)

        {

            printf("%c     ",g->vexs[vexcount]);

        }

        printf("\n\n");

        for (int j=0;j<g->vexnum;j++)

        {

            printf("%d-->%d: ",i+1,j+1);

            for (int k=0;k<g->vexnum;k++)

            {

                printf("%d     ",P[i][j][k]);

            }

            printf("\n\n");

        }

        printf("-----------------------------------------\n");

    }

}



void ShortestPath_Folyd(MGraph g,PathMatrix &P,DistancMatrix &D)

{    //用Floyd算法求有向网G中各对顶点v和w之间的最短路径P[v][w]及其带权长

    //度D[v][w],若p[v][w][u]为TRUE,则u是从v到w当前求的最短路径上的顶点

    int u,v,w,i;

    for (v=0;v<g->vexnum;++v)        //对各节点之间初始已知路径及距离

        for (w=0;w<g->vexnum;++w)

        {

            D[v][w]=g->arcs[v][w].adj;

            for (u=0;u<g->vexnum;++u)

                P[v][w][u]=FALSE;                    

            if (D[v][w]<INFINITY)        //从v到w有直接路径

            {

                P[v][w][v]=TRUE;        //起点

                P[v][w][w]=TRUE;        //终点

            }//if

        }



        for (u=0;u<g->vexnum;++u)

            for (v=0;v<g->vexnum;++v)

                for (w=0;w<g->vexnum;++w)

                {

                    if(u==v || v==w || w==u)

                        continue;

                    if (D[v][u]+D[u][w]<D[v][w])    //从v经u到w的一条路径更短

                    {

                        D[v][w]=D[v][u]+D[u][w];

                        for (i=0;i<g->vexnum;++i)

                            P[v][w][i]=P[v][u][i]||P[u][w][i];

                    }//if

                }

}//ShortestPath_Floyd



int main()

{

//    freopen("in","r",stdin);//freopen("out","w",stdout);

    MGraph g;

    Init_graph(g);

    Create_mgraph(g);

    Print_mgraph(g);



    DistancMatrix D;

    PathMatrix P;

    ShortestPath_Folyd(g,P,D);



    Print_DistancMatrix(g,D);

    Print_PathMatrix(g,P);

    return 0;

}

输入数据:

 

6
123456
10
5 1 2
7 1 4
4 2 3
8 3 1
9 3 6
5 4 3
6 4 6
5 5 4
3 6 1
1 6 5

执行结果为:

Floyd算法思想及实现Floyd算法思想及实现Floyd算法思想及实现

 

你可能感兴趣的:(floyd)