C语言 最短路径之Dijkstra算法 无向图

本文详细介绍Dijkstra算法,一种用于寻找图中两点间最短路径的经典算法。文章通过具体实例介绍了算法的基本原理、实现过程及代码实现细节。

Dijkstra算法简介

Dijkstra算法是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。
这里写图片描述

实现过程

Dijkstra算法和Prim算法非常相似(参照链接:C语言 Prim算法和Kruskal算法的实现和证明

这里写图片描述

这里写图片描述

这里写图片描述

从上面可以看出,Dijkstra算法只是比Prim算法多增加了一个在之后重新计算距离的步骤而已。总的过程:
这里写图片描述

代码实现

核心代码:

void changeWeight(AdjGraphPtr adj, int *distTo, int pos) {
    EdgePtr tmp = adj->vertexList[pos]->firstEdge;
    while (tmp != NULL) {
        VTYPE to = getVertexPos(adj, tmp->w);
        if (distTo[to] != INFINITE) {
            tmp = tmp->next;
            continue;
        }
        tmp->weight = tmp->weight + distTo[pos];
        tmp = tmp->next;
    }
}

void insertEdgeToQueue(AdjGraphPtr spt, QueuePtr minPQ, EdgePtr edge) {
    VTYPE a = edge->v;
    VTYPE b = edge->w;
    int weight = edge->weight;
    int pos_a = getVertexPos(spt, a);

    EdgePtr tmp = spt->vertexList[pos_a]->firstEdge;
    while (tmp != NULL) {
        if (edge->v == tmp->v && edge->w == tmp->w) {
            return;
        }
        if (edge->w == tmp->v && edge->v == tmp->w) {
            return;
        }
        tmp = tmp->next;
    }

    insertQueue(minPQ, edge, 1);
}

BOOLEAN isMarkedAll(int *distTo, int length) {
    for (int i = 0; i < length; i++) {
        if (distTo[i] == INFINITE) {
            return FALSE;
        }
    }
    return TRUE;
}

void dijkstraSPT(AdjGraphPtr adj) {
    /**********初始化********/
    QueuePtr minPQ = createQueue();  //保存横截边

    AdjGraphPtr spt = (AdjGraphPtr)malloc(sizeof(AdjGraph));  //保存路径
    memset(spt, 0, sizeof(AdjGraph));
    for (int i = 0; i < adj->vNum; i++) {
        insertVertex(spt, adj->vertexList[i]->v);
    }
    spt->vNum = adj->vNum;

    int distTo[6]; //保存距离,标记顶点
    for (int i = 0; i < 6; i++) {
        distTo[i] = INFINITE;
    }
    /**********初始化********/

    EdgePtr tmp = adj->vertexList[0]->firstEdge;
    while(tmp != NULL) {
        insertQueue(minPQ, tmp, 1);
        tmp = tmp->next;
    }
    distTo[0] = 0;

    while (isQueueEmpty(minPQ) == FALSE && isMarkedAll(distTo, 6)==FALSE) {
        EdgePtr minEdge = outQueue(minPQ);
        VTYPE from = minEdge->v;
        VTYPE to = minEdge->w;
        int weight = minEdge->weight;

        int toPos = getVertexPos(adj, to);
        distTo[toPos] = weight;

        insertEdge(spt, from, to, weight);
        insertEdge(spt, to, from, weight);
        changeWeight(adj, distTo, toPos);


        EdgePtr t
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值