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中集合内部的边不可忽略,长度存在

时间: 2024-10-11 22:56:03

Prim算法与Dijkstra算法的联系与区别的相关文章

数据结构与算法系列研究七——图、prim算法、dijkstra算法

图.prim算法.dijkstra算法 1. 图的定义 图(Graph)可以简单表示为G=<V, E>,其中V称为顶点(vertex)集合,E称为边(edge)集合.图论中的图(graph)表示的是顶点之间的邻接关系. (1) 无向图(undirect graph)      E中的每条边不带方向,称为无向图.(2) 有向图(direct graph)      E中的每条边具有方向,称为有向图.(3) 混合图       E中的一些边不带方向, 另一些边带有方向.(4) 图的阶      指

最小生成树算法之 Dijkstra算法

Dijkstra算法 Dijkstra算法是典型最短路算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低. Dijkstra算法是用来求任意两个顶点之间的最短路径.在该算法中,我们用邻接矩阵来存储图.在该程序中设置一个二维数组来存储任意两个顶点之间的边的权值.可以将任意一个图的信息通过键盘输入,让后在输入要查找的两个顶点,程序可以自动求出这两个顶点之间的最短路

最短路径算法(Dijkstra算法、Floyd-Warshall算法)

最短路径算法具体的形式包括: 确定起点的最短路径问题:即已知起始结点,求最短路径的问题.适合使用Dijkstra算法. 确定终点的最短路径问题:即已知终结结点,求最短路径的问题.在无向图中,该问题与确定起点的问题完全等同:在有向图中,该问题等同于把所有路径方向反转的确定起点的问题. 确定起点终点的最短路径问题:即已知起点和终点,求两结点之间的最短路径. 全局最短路径问题:求图中所有的最短路径.Floyd-Warshall算法. dijkstra算法思想: 开始时,S={u},T=V-{u}; 对

数据结构与算法——最短路径Dijkstra算法的C++实现

之前的讨论了无权图的最短路径算法.数据结构与算法--无权最短路径算法的C++实现 如果是加权图,那么问题就变得困难了,不过仍然可以采用无权情况的想法. 我们仍然保留之前的信息.因此,每个顶点会被标记为known或unknown,每个顶点保留一个尝试性的距离dv(这个距离是只使用一些known顶点作为中间顶点从s到v的最短路径的长),每个顶点还保留字段pv,该字段是记录引起dv变化的最后的顶点. 图顶点信息的数据结构: //保存每个顶点信息的数据结构 struct GraphNode{ bool

图中最短路径算法(Dijkstra算法)(转)

1.Dijkstra 1)      适用条件&范围: a)   单源最短路径(从源点s到其它所有顶点v); b)   有向图&无向图(无向图可以看作(u,v),(v,u)同属于边集E的有向图) c)   所有边权非负(任取(i,j)∈E都有Wij≥0); 2)      算法描述: 在带权图中最常遇到的问题就是,寻找两点间的最短路径问题. 解决最短路径问题最著名的算法是Djikstra算法.这个算法的实现基于图的邻接矩阵表示法,它不仅能够找到任意两点的最短路径,还可以找到某个指定点到其他

最短路径算法之Dijkstra算法(java实现)

前言 Dijkstra算法是最短路径算法中为人熟知的一种,是单起点全路径算法.该算法被称为是“贪心算法”的成功典范.本文接下来将尝试以最通俗的语言来介绍这个伟大的算法,并赋予java实现代码. 一.知识准备: 1.表示图的数据结构 用于存储图的数据结构有多种,本算法中笔者使用的是邻接矩阵.  图的邻接矩阵存储方式是用两个数组来表示图.一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中的边或弧的信息. 设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为: 从上面可以看出,无向图的边

【数据结构】拓扑排序、最短路径算法、Dijkstra算法、无环图等等

图的定义 图(graph)G = (V,E)由顶点(vertex)的集V和边(Edge)的集E组成.有时也把边称作弧(arc),如果点对(v,w)是有序的,那么图就叫做有向的图(有向图).顶点v和w邻接(adjacent)当且仅当(v,w)属于E. 如果无向图中从每一个顶点到其他每个顶点都存在一条路径,则称该无向图是连通的(connected).具有这样性质的有向图称为是强连通的(strongly connected).如果有向图不是强连通的,但它的基础图(underlying graph)(也

图论(三) (一)最短路径算法 2.Dijkstra算法

Dijkstra 算法解决的是带权重的有向图上单源最短路径问题,该算法要求所有边的权重都为非负值.该算法的时间复杂度是O(N2),相比于处理无负权的图时,比Bellmad-Ford算法效率更高. 算法描述: 首先引用<算法导论>中的一段比较官方的话,如果可以看懂,那下一部分就可以跳过了: "Dijkstra算法在运行过程中维持的关键信息是一组结点集合S.从源结点s到该集合中每个结点之间的最短路径已经被找到.算法重复从结点集 V - S 中算则最短路径估计的最小的结点 u ,将 u 加

求最短路径(Bellman-Ford算法与Dijkstra算法)

前言 Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的.这时候,就需要使用其他的算法来求解最短路径,Bellman-Ford算法就是其中最常用的一个. 在网络路由中,RIP协议(距离向量路由算法)一般用Bellman-Ford算法,同时由于简单性所以也适用于分布式系统:但是它的复杂度是O(VE),比Dijkstra算法要慢上许多.而OSPF协议,链路状态分组创建的时候一般用Dijkst