用Dijkstra算法实现最短路径——C语言

/**
 * @Author: fanzhang
 * @Date: 2019-02-26 19:51:09
 * @Desc:  Dijkstra最短路径算法
 */
#include <stdio.h>
#include <stdlib.h>
#define Max 1000000
typedef struct
{
    int fromvex, endvex; //边的起点和终点
    float length;
} edge;
//float dist[][]
void diskstra(int v, float** dist, float* D, int* p, int* s, int n);
void creatadjarry(float** dist, int n, int e);
int main(int argc, char const* argv[])
{
    int e, n, i;
    float** dist; //
    printf("输入图的顶点数和边数:");
    scanf("%d%d", &n, &e);
    dist = (float**)malloc(sizeof(float) * n);
    for (i = 0; i < n; i++)
        dist[i] = (float*)malloc(sizeof(float) * n);
    float* D = (float*)malloc(sizeof(float) * n);
    int* p = (int*)malloc(sizeof(int) * n);
    int* s = (int*)malloc(sizeof(int) * n);
    creatadjarry(dist, n, e);
    diskstra(0, dist, D, p, s, n);
    free(dist);
    free(D);
    free(p);
    free(s);
    return 0;
}
void diskstra(int v, float** dist, float* D, int* p, int* s, int n)
{ //求源点v到其他各点的最短路径及长度
    int i, j, k, v1, min, max = 10000, pre; //max表示无穷大
    v1 = v;
    for (i = 0; i < n; i++) {
        D[i] = dist[v][i];
        if (D[i] != max)
            p[i] = v1 + 1;
        else
            p[i] = 0;
        s[i] = 0;
    }
    s[v1] = 1; //将源点送入u
    for (i = 0; i < n - 1; i++) {
        min = 10001;
        for (j = 0; j < n - 1; j++)
            if ((!s[j]) && D[j] < min) {
                min = D[j];
                k = j;
            }
        s[k] = 1; //将找到的顶点k送入u
        for (j = 0; j < n; j++)
            if (!s[j] && (D[j] > D[k] + dist[k][j])) {
                D[j] = D[k] + dist[k][j];
                p[j] = k + 1;
            }
    }
    for (i = 0; i < n; i++) { //输出路径
        printf("路径长度: %-6g  路径: %c", D[i], 'A' + i);
        pre = p[i];
        while ((pre != 0) && (pre != v + 1)) {
            printf(" << %c", 'A' + pre - 1);
            pre = p[pre - 1];
        }
        printf(" << %c", 'A' + v);
        printf("\n");
    }
    printf("\n");
}
void creatadjarry(float** dist, int n, int e) //创建邻接矩阵
{
    int i, j;
    for (i = 0; i < n; i++) { //赋初值
        for (j = 0; j < n; j++)
            dist[i][j] = Max;
        dist[i][i] = 0;
    }
    for (int a = 0; a < e; a++) {
        printf("输入第%d条边的顶点终点和权值:", a + 1);
        scanf("%d%d", &i, &j);
        scanf("%f", &dist[i][j]);
    }
}

运行结果

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值