Dijkstra算法

1、Dijkstra算法:是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。这个算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。注意该算法要求图中不存在负权边。

2、Dijkstra算法的思路:该算法主要是根据最短路径的不断更新,最后获得最短路径。在最开始确定起点和目的点,将起点的邻接点路径长设置为权重,将其他顶点设置为无穷大,依次访问邻接点,比较V+E(v,w)与Dist[w]的值,如果比他小,说明有更短的路径,就更新Dist[w]和path[w],不断地这样进行,知道所有的元素都被访问过后,就退出循环,得到最短路径。路径可以追溯path数组得到,思路流程图如图所示:
这里写图片描述
具体的通过例子进行理解。

3、Dijsktra算法的例子:
这里写图片描述
寻找最短路径的步骤:
(1)、确定起点V1,并初始化dist[1]=0,dist[2]=2,dist[4]=1,其他的初始化为正无穷,初始化后如图:
这里写图片描述

(2)、然后访问V2和V4其中路径短的那个,这里先访问V4,然后比较V4与邻接点之间的权重相加,如1+E(v4+v7)=5<正无穷,更新dist[7]=5和path[7]=4,同样的方法处理v5和v6。更新过后数组如图:
这里写图片描述
(3)、以此类推,继续访问知道所有的结点被标记访问退出。

代码实现:

Vertex FindMinDist( MGraph Graph, int dist[], int collected[] )
{ /* 返回未被收录顶点中dist最小者 */
    Vertex MinV, V;
    int MinDist = INFINITY;

    for (V=0; V<Graph->Nv; V++) {
        if ( collected[V]==false && dist[V]<MinDist) {
            /* 若V未被收录,且dist[V]更小 */
            MinDist = dist[V]; /* 更新最小距离 */
            MinV = V; /* 更新对应顶点 */
        }
    }
    if (MinDist < INFINITY) /* 若找到最小dist */
        return MinV; /* 返回对应的顶点下标 */
    else return ERROR;  /* 若这样的顶点不存在,返回错误标记 */
}

bool Dijkstra( MGraph Graph, int dist[], int path[], Vertex S )
{
    int collected[MaxVertexNum];
    Vertex V, W;

    /* 初始化:此处默认邻接矩阵中不存在的边用INFINITY表示 */
    for ( V=0; V<Graph->Nv; V++ ) {
        dist[V] = Graph->G[S][V];
        if ( dist[V]<INFINITY )
            path[V] = S;
        else
            path[V] = -1;
        collected[V] = false;
    }
    /* 先将起点收入集合 */
    dist[S] = 0;
    collected[S] = true;

    while (1) {
        /* V = 未被收录顶点中dist最小者 */
        V = FindMinDist( Graph, dist, collected );
        if ( V==ERROR ) /* 若这样的V不存在 */
            break;      /* 算法结束 */
        collected[V] = true;  /* 收录V */
        for( W=0; W<Graph->Nv; W++ ) /* 对图中的每个顶点W */
            /* 若W是V的邻接点并且未被收录 */
            if ( collected[W]==false && Graph->G[V][W]<INFINITY ) {
                if ( Graph->G[V][W]<0 ) /* 若有负边 */
                    return false; /* 不能正确解决,返回错误标记 */
                /* 若收录V使得dist[W]变小 */
                if ( dist[V]+Graph->G[V][W] < dist[W] ) {
                    dist[W] = dist[V]+Graph->G[V][W]; /* 更新dist[W] */
                    path[W] = V; /* 更新S到W的路径 */
                }
            }
    } /* while结束*/
    return true; /* 算法执行完毕,返回正确标记 */
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值