• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
千里之行,始于足下。
探索程序的世界
博客园    首页    新随笔    联系   管理    订阅  订阅
Prim算法与Dijkstra算法的联系与区别
寻求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中集合内部的边不可忽略,长度存在

posted on 2015-08-17 23:06  bajdcc  阅读(716)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3