图论--Floyd_Warshall算法---邻接矩阵实现

来源:互联网 发布:竞品调研报告知乎 编辑:程序博客网 时间:2024/04/30 06:27

Floyd_Warshall算法---邻接矩阵实现

                         求每个点到其它点的最短路径。

C语言实现:

                       除核心算法外,其他函数有的可以优化。

                       例如:层次 遍历。

代码实现:

#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAX_LEN 20#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INTMAX 0xFFFFtypedef char type[20];int visit[MAX_LEN];typedef struct MGraph{///--------------图    type vexs[MAX_LEN];//----顶点信息    int vexnum;        //----顶点数    int arcnum;        //----弧数(边数)    int dist[MAX_LEN][MAX_LEN];//-----权值    //int kind;}MGraph;typedef struct Queue{///---------------广度优先遍历--队列----    int front;    int rear;    int data[MAX_LEN+1];}Queue;void CreateGraph( MGraph * g )///-------------------建立有向图----------------------------{    int i , j , k , weight;    type v1 , v2 ;    printf("请输入顶点数,边数:\n");    scanf("%d %d",&g->vexnum , &g->arcnum );    printf("\n请输入%d定点信息:\n",g->vexnum);    for( i = 0 ; i < g->vexnum ; i++)        scanf("%s",g->vexs[i]);    for( i = 0 ; i < g->vexnum ; i++)        for( j = 0 ; j < g->vexnum ; j++){            g->dist[i][j] = INTMAX;        }    printf("\n请输入%d条弧的 两两关系 及 权值 :\n",g->arcnum);    for( k = 0 ; k < g->arcnum ;  k++){        scanf("%s %s %d",&v1 , &v2 ,&weight);        i = LocateVex( g , v1 );        j = LocateVex( g , v2 );        g->dist[i][j] = weight;    }}int LocateVex( MGraph * g , type v )///-----------------查找匹配函数{    int i ;    for( i = 0 ; i < g->vexnum ; i++)    {        if( (strcmp( v , g->vexs[i])) == 0 )            return i;    }}int FirstAdjVex( MGraph * g , int i )///-----------------开始寻找函数{    int j , p = -1;    for( j = 0 ; j < g->vexnum ; j++){        if( g->dist[i][j] != INTMAX ){            p = j;            break;        }    }    return p;}int NextAdjVex( MGraph * g , int i , int k )///----------------寻找下一个顶点{    int j , p = -1;    for( j = k+1 ; j < g->vexnum ; j ++){        if( g->dist[i][j] != INTMAX ){            p = j ;            break;        }    }    return p;}void Floyd_Warshall( MGraph * g )///--------------------floyd_warshall算法----------------------------{    int i , j , k;    for( i = 0 ; i < g->vexnum ; i ++ )        g->dist[i][i] = 0;    for( i = 0 ; i < g->vexnum ; i ++ )        for( j = 0 ; j < g->vexnum ; j ++ )            for( k = 0 ; k < g->vexnum ; k ++ )                if( g->dist[j][i] != INTMAX && g->dist[i][k] != INTMAX && g->dist[j][i]+g->dist[i][k] < g->dist[j][k] )                    g->dist[j][k] = g->dist[j][i]+g->dist[i][k];    ShowPathWay( g );}void ShowPathWay( MGraph * g )///--------------输出最短路径的值---------------------------{    int i , j;    printf("\n最短路径:\n");    for( i = 0 ; i < g->vexnum ; i++)        for( j = 0 ; j < g->vexnum ; j++){            if( g->dist[i][j] != INTMAX ){                printf("%s-->%s: \n",g->vexs[i],g->vexs[j]);                printf("pathway = %d\n",g->dist[i][j]);            }            else{                printf("%s-->%s: \n",g->vexs[i],g->vexs[j]);                printf("ERROR\n");            }    }}///------------------------------------深度优先遍历----------------------------------void Dfs( MGraph * g , int i ){    int j;    visit[i] = TRUE;    printf("%s ",g->vexs[i]);    for( j = FirstAdjVex( g, i ) ; j >= 0 ; j = NextAdjVex( g , i , j )){        if(!visit[j]){            Dfs( g , j);        }    }}void DfsTraverse( MGraph * g ){    int i;    for( i = 0 ; i <g->vexnum ; i ++)        visit[i] = FALSE;    for( i = 0 ; i <g->vexnum ; i ++)        if(!visit[i])            Dfs(g , i);}///---------------------------------------广度优先遍历----(队列实现)-------void InitQueue( Queue * Q ){    Q->front = Q->rear = 0;}int IsEmpty( Queue * Q ){    return Q->front == Q->rear;}void EnQueue( Queue * Q , int value ){    Q->data[Q->rear] = value ;    Q->rear = Q->rear+1;}int DeQueue( Queue * Q ){    int k;    if(IsEmpty(Q)){        return ERROR;    }    else{        k = Q->data[Q->front];        Q->front = Q->front+1;    }    return k;}void BFSTraverse( MGraph * g ){    int i , j ;    Queue Q;    for( i = 0 ; i < g->vexnum ; i++)        visit[i] = FALSE;    InitQueue(&Q);    for( i = 0 ; i < g->vexnum ; i++)        if( !visit[i]){            visit[i] = TRUE;            EnQueue( &Q , i);            printf("%s ",g->vexs[i]);            while( !IsEmpty( &Q )){                int k;                k = DeQueue( &Q );                for( j = FirstAdjVex(g , k) ; j>= 0 ; j = NextAdjVex(g , k , j) ){                    if( ! visit[j] ){                        visit[j] = TRUE;                        printf("%s ",g->vexs[j]);                        EnQueue( &Q , j );                    }                }            }        }}int main()///--------------------main()-------------{    int T ;    printf("--------------------Floyd-warshall算法-----(有向图)----------------------------\n");    printf("请输入测试数据的组数:\n");    scanf("%d",&T);    while( T-- )    {        MGraph g;        CreateGraph( &g );        printf("\n深度优先遍历:\n");        DfsTraverse( &g );        printf("\n\n广度优先遍历:\n");        BFSTraverse( &g );        printf("\n--------------Floyd_Warshall算法----------------------------------------\n");        Floyd_Warshall( &g );        printf("\n\n--------------------------------------------------------------------\n\n");    }    return 0;}

 

案例:

--------------------Floyd-warshall算法------(有向图)--------------------------
请输入测试数据的组数:
3
请输入顶点数,边数:
7 12

请输入7定点信息:
1 2 3 4 5 6 7

请输入12条弧的 两两关系 及 权值 :
1 2 2
1 4 1
2 4 3
2 5 10
3 1 4
3 6 5
4 3 2
4 5 2
4 6 8
4 7 4
5 7 6
7 6 1

深度优先遍历:
1 2 4 3 6 5 7

广度优先遍历:
1 2 4 5 3 6 7
--------------Floyd_Warshall算法----------------------------------------

最短路径:
1-->1:
pathway = 0
1-->2:
pathway = 2
1-->3:
pathway = 3
1-->4:
pathway = 1
1-->5:
pathway = 3
1-->6:
pathway = 6
1-->7:
pathway = 5
2-->1:
pathway = 9
2-->2:
pathway = 0
2-->3:
pathway = 5
2-->4:
pathway = 3
2-->5:
pathway = 5
2-->6:
pathway = 8
2-->7:
pathway = 7
3-->1:
pathway = 4
3-->2:
pathway = 6
3-->3:
pathway = 0
3-->4:
pathway = 5
3-->5:
pathway = 7
3-->6:
pathway = 5
3-->7:
pathway = 9
4-->1:
pathway = 6
4-->2:
pathway = 8
4-->3:
pathway = 2
4-->4:
pathway = 0
4-->5:
pathway = 2
4-->6:
pathway = 5
4-->7:
pathway = 4
5-->1:
ERROR
5-->2:
ERROR
5-->3:
ERROR
5-->4:
ERROR
5-->5:
pathway = 0
5-->6:
pathway = 7
5-->7:
pathway = 6
6-->1:
ERROR
6-->2:
ERROR
6-->3:
ERROR
6-->4:
ERROR
6-->5:
ERROR
6-->6:
pathway = 0
6-->7:
ERROR
7-->1:
ERROR
7-->2:
ERROR
7-->3:
ERROR
7-->4:
ERROR
7-->5:
ERROR
7-->6:
pathway = 1
7-->7:
pathway = 0

原创粉丝点击