数据结构 | 图的最短路径 Floyd算法

一、数据结构定义

typedef int VertexType;
typedef int EdgeType;

/*图*/
typedef struct {
    VertexType Vexs[SIZE];		//结点 
    EdgeType Edges[SIZE][SIZE];	//权值 
    int vexnum, arcnum;
}MGraph;

/*路径*/
typedef struct {
    int path[SIZE][SIZE];
    EdgeType length;
}Path;

1.二维数组 Edges[SIZE][SIZE] 储存图的边权数据,一维数组 Vexs[SIZE] 储存图的结点数据;

2.结构体 Path 保存计算后的路径信息。

二、算法详解

/* 初始化图并输入权值 */
MGraph* InitGraph() {
    MGraph* G = (MGraph*)malloc(sizeof(MGraph));
    G->vexnum = 4;
    G->arcnum = 8;
    //初始化图的邻接矩阵 Edges[SIZE][SIZE]
    for (int i = 0; i < G->vexnum; i++) {
        for (int j = 0; j < G->vexnum; j++) {
            if (i == j)	G->Edges[i][j] = 0;		//对角线权值为0 
            else		G->Edges[i][j] = MaxNum;	//除对角线外所有权值为无穷大 
        }
    }
    //初始化图的结点矩阵 Vexs[SIZE]
    VertexType v[4] = { 0,1,2,3 };
    for (int i = 0; i < G->vexnum; i++)
        G->Vexs[i] = v[i];
    //初始化图的边权
    int  start_vex[8] = { 0,0,1,1,2,2,2,3 };
    int    end_vex[8] = { 1,3,2,3,0,1,3,2 };
    int vex_weight[8] = { 5,7,4,2,3,3,2,1 };
    for (int i = 0; i < G->arcnum; i++)
        G->Edges[start_vex[i]][end_vex[i]] = vex_weight[i];
    return G;
}

/* 初始化路径矩阵 */
Path InitPath() {
    Path path;
    path.length = 0;
    return path;
}

/* Floyd算法寻找最短路径 */
void Floyd(MGraph* Graph, Path *path) {
    int i, j, k, nun = Graph->vexnum;
    int temp[SIZE][SIZE];
    // 初始化
    for (i = 0; i < nun; i++) {
        for (j = 0; j < nun; j++) {
            temp[i][j] = Graph->Edges[i][j];
            path->path[i][j] = -1;
        }
    }
    // 算法主体
    for (k = 0; k < nun; k++) {
        for (i = 0; i < nun; i++) {
            for (j = 0; j < nun; j++) {
                if (temp[i][j] > temp[i][k] + temp[k][j]) {
                    temp[i][j] = temp[i][k] + temp[k][j];
                    path->path[i][j] = k;
                }
            }
        }
    }
}

三、运行结果

        main方法代码如下:

int main() {
    MGraph* Graph = InitGraph();
    Path path = InitPath();

    Floyd(Graph, &path);
    PrintPath(Graph, &path);
    return 0;
}

 

四、源代码

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

#define SIZE 4          //邻接矩阵大小(v0 - v3)
#define MaxNum 999      //不可到达点的权值(即无穷大)

typedef int VertexType;
typedef int EdgeType;

/*图*/
typedef struct {
    VertexType Vexs[SIZE];		//结点 
    EdgeType Edges[SIZE][SIZE];	//权值 
    int vexnum, arcnum;
}MGraph;

/*路径*/
typedef struct {
    int path[SIZE][SIZE];
    EdgeType length;
}Path;


/* 初始化图并输入权值 */
MGraph* InitGraph() {
    MGraph* G = (MGraph*)malloc(sizeof(MGraph));
    G->vexnum = 4;
    G->arcnum = 8;
    //初始化图的邻接矩阵 Edges[SIZE][SIZE]
    for (int i = 0; i < G->vexnum; i++) {
        for (int j = 0; j < G->vexnum; j++) {
            if (i == j)	G->Edges[i][j] = 0;		//对角线权值为0 
            else		G->Edges[i][j] = MaxNum;	//除对角线外所有权值为无穷大 
        }
    }
    //初始化图的结点矩阵 Vexs[SIZE]
    VertexType v[4] = { 0,1,2,3 };
    for (int i = 0; i < G->vexnum; i++)
        G->Vexs[i] = v[i];
    //初始化图的边权
    int  start_vex[8] = { 0,0,1,1,2,2,2,3 };
    int    end_vex[8] = { 1,3,2,3,0,1,3,2 };
    int vex_weight[8] = { 5,7,4,2,3,3,2,1 };
    for (int i = 0; i < G->arcnum; i++)
        G->Edges[start_vex[i]][end_vex[i]] = vex_weight[i];
    return G;
}

/* 初始化路径矩阵 */
Path InitPath() {
    Path path;
    path.length = 0;
    return path;
}

/* Floyd算法寻找最短路径 */
void Floyd(MGraph* Graph, Path *path) {
    int i, j, k, nun = Graph->vexnum;
    int temp[SIZE][SIZE];
    // 初始化
    for (i = 0; i < nun; i++) {
        for (j = 0; j < nun; j++) {
            temp[i][j] = Graph->Edges[i][j];
            path->path[i][j] = -1;
        }
    }
    // 算法主体
    for (k = 0; k < nun; k++) {
        for (i = 0; i < nun; i++) {
            for (j = 0; j < nun; j++) {
                if (temp[i][j] > temp[i][k] + temp[k][j]) {
                    temp[i][j] = temp[i][k] + temp[k][j];
                    path->path[i][j] = k;
                }
            }
        }
    }
}

/* 递归寻找最短路径 */
void FindPath(int start, int end, Path* path, MGraph* Graph) {
    if (path->path[start][end] == -1) {
        printf("-> %d ", end);
        path->length = path->length + Graph->Edges[start][end];
    }
    else {
        int mid = path->path[start][end];
        FindPath(start, mid, path, Graph);
        FindPath(mid, end, path, Graph);
    }
}

/* 打印最短路径 */
void PrintPath(MGraph* Graph, Path* path) {
    VertexType start, end;
    printf("输入起点:");
    scanf("%d", &start);
    printf("输入终点:");
    scanf("%d", &end);

    printf("%d ", start);
    FindPath(start, end, path, Graph);
    printf("= %d", path->length);
}

int main() {
    MGraph* Graph = InitGraph();
    Path path = InitPath();

    Floyd(Graph, &path);
    PrintPath(Graph, &path);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sun80760/article/details/131710863
今日推荐