数据结构——第七讲、图(中)(1)

7.1 最短路径问题

最短路径问题分为:单源最短路径和多源最短路径。

单源最短路径:

单源无全图的算法思想:从源点开始一圈一圈往外扩展,依次找到与源点距离为1的,与源点距离为2的节点,对广度优先搜索(BFS)稍作修改即可。

void Unweighted( Vertex S ){
    int Dest[N] = {-1};
    Vertex Path[];
    EnQueue( S,Q );
    Dest[S] = 0;
    while( !IsEmpty Q ){
        V = DelQueue(Q);
        for(V的每一个邻接点W){
            if( Dist[W] == -1){
                //到W的距离等于到V的距离加1
                Dist[W] = Dist[V]+1;
                //到达W的最短路径必须经过V
                Path[W] = V;
            }
        }
    }
}

单源有权图的算法(dijkstra算法):有一个集合S,它里面收录了源点和已经找到最短路径的点,按照距离非递减的顺序依次把所有的点都收录到S里面。

//需要把Dist初始化为正无穷,Path初始化为-1
void Dijkstra(VerTex V){
    Dest[V] = 0;
    Collected[V] = true;
    for(V的每一个邻接点W){
        //E<V,W>bi表示V到W的距离,也就是权重。
        Dest[W] = E<V,W>;
    }
    while(1){
        V = 还未收录的节点的Dest最小的节点。
        if(所有的节点都被收录)break;
        Collected[V] = true;
        for(V的每一个邻接点){
            if( Collected[W] == false ){
                if(Dist[V] + E<V,W> < Dist[W]){
                    Dist[W] = Dist[V] + E<V,W>;
                    Path[W] = V;
                }
            }
        }
    }
}

多源最短路径:

方法一:可以直接把单源最短路径的方法对每一个节点都调用一遍(对稀疏图效果好)。

方法二:Floyd算法

bool Floyd( MGraph Graph, WeightType D[][MaxVertexNum], Vertex path[][MaxVertexNum] )
{
    Vertex i, j, k;

    /* 初始化 */
    for ( i=0; i<Graph->Nv; i++ )
        for( j=0; j<Graph->Nv; j++ ) {
            D[i][j] = Graph->G[i][j];
            path[i][j] = -1;
        }

    for( k=0; k<Graph->Nv; k++ )
        for( i=0; i<Graph->Nv; i++ )
            for( j=0; j<Graph->Nv; j++ )
                if( D[i][k] + D[k][j] < D[i][j] ) {
                    D[i][j] = D[i][k] + D[k][j];
                    if ( i==j && D[i][j]<0 ) /* 若发现负值圈 */
                        return false; /* 不能正确解决,返回错误标记 */
                    path[i][j] = k;
                }
    return true; /* 算法执行完毕,返回正确标记 */
}

猜你喜欢

转载自blog.csdn.net/github_39312212/article/details/78304108