Prim算法与Dijkstra算法的联系与区别

/* 图结构,邻接矩阵形式 */

ElemType nodes[n];

int edges[n][n];


prim_or_dijkstra( int index, bool usePrim )     /* 起点 */

{
    int dist[n] = { INF };                  /* 从起点开始,到其他所有边的距离 */

    int distIndex[n] = { -1 };

    int visited[n] = { 0 };

    int selected = index;                   /*选中的点 */

/* 初始化起点的可达边距离 */

    for ( i = 0; i < nodes.length; i++ )

/* edges[起点][终点]=权重(不是INF就有边),穷举 */

    {
        if ( visited[i] )
            break;

        visited[i] = true;

        if ( edges[selected][i] != INF )
        {
            dist[i] = edges[selected][i];   /* index到可达边的距离 */
        }
    }


    for ( k = 0; k < nodes.length - 1; k++ )        /* n-1次循环取点 */

    {
        visited[selected] = true;

        int min = INF;

        int sel = -1;

        for ( i = 0; i < nodes.length; i++ )

/* edges[起点][终点]=权重(不是INF就有边),穷举 */

        {
            if ( visited[i] )
                break;  /* 属于同一集合,不必考虑 */

            if ( edges[selected][i] != INF )
            {
                if ( min > dist[i] )
                {
                    min = dist[i]; sel = i;
                }

/* min=已经被选中的点的集合到其他单独的点的最短距离 */

/* sel=相应的点 */
            }
        }

        distIndex[sel] = selected; /* sel->selected映射,存放边 */

/* 一个sel只对应一个selected, */

/* 一个selected对应多个sel */

/* 第一次distIndex v2->v1 */

        selected = sel; /*选中的点要更新 */

/* 此时 */

/* prim中令 dist[selected]=0 */

/* dijkstra不添加代码 */

        if ( usePrim )
        {
            dist[selected] = 0;
        }

        for ( i = 0; i < nodes.length; i++ ) /* selected->i,更新其他边 */

/* 由于selected已经是集合的一部分, */

/* selected的可达边的距离属于集合的可达边的距离 */

        {
/* 在所有的集合的可达边(不包含集合自身)的距离中取较小值 */

/*下面是两种方法相同的部分 */

            if ( !visited[i]

                 && dist[i] > dist[selected] + edges[selected][i] )

            {
                dist[i] = dist[selected] + edges[selected][i]
            }
        }
    }

联系:

两者在连边时,用的是同一种贪心策略,即对于将扩展的集合总是在非扩展的点中找一条最短的边入集合,并用新入集合的点修改剩下点的到集合的最短路。

共同点:都有visited标记数组,dist数组,min,distIndex数组

注意:网上大多数教程中,prim算法是没有visited数组的,它用令dist[]=0来简化,而在这里,两种方法都用了visited数组,减少了差异性

区别:

在于dist的修改和意义

dijkstra仅仅就多了一个dist[selected],用做累积距离

而prim中由于dist[selected]=0,故可消去dist[selected]

prim

if(!visited[i] && dist[i] > edges[selected][i])

{dist[i] = edges[selected][i];}

//解释:prim中集合内部的边看做短路,可忽略,长度为0

dijkstra

if(!visited[i]

&& dist[i] > dist[selected]+ edges[selected][i])

{dist[i] = dist[selected]+ edges[selected][i]}

//解释:dijkstra中集合内部的边不可忽略,长度存在

原文地址:https://www.cnblogs.com/bajdcc/p/4738070.html