图的遍历、拓扑排序、最短路径算法

//深度优先遍历:
void DFSTraverse ( Graph G )
{
  visited [0 .. G.vexnum-1] = false;   // 初始化访问标志为未访问(false)
  for ( v = 0; v < G.vexnum; v ++ )
    if ( ! visited[v] )  DFS ( G, v );  // 从未被访问的顶点开始DFS
}

void DFS ( Graph G, int v )
{
  visit ( v );  visited [v] = true;   // 访问顶点v并作标记
  for ( w = FirstAdjVex(G,v); w >= 0; w = NextAdjVex(G,v,w) )
    if ( ! visited[w] )  DFS ( G, w );  // 分别从每个未访问的邻接点开始DFS
}
//广度优先遍历:利用队列(类似按层遍历二叉树)。
void BFSTraverse ( Graph G )
{
  visited [0 .. G.vexnum-1] = false;   // 初始化访问标志为未访问(false)
  InitQueue ( Q );
  for ( v = 0; v < G.vexnum; v++ )
    if ( ! visited[v] )
    {
      // 从v出发广度优先搜索
      visit ( v );  visited [v] = true;
      EnQueue ( Q, v );
      while ( ! QueueEmpty(Q) )
      {
        DeQueue ( Q, u );
        for ( w = FirstAdjVex(G,u); w >= 0; w = NextAdjVex(G,u,w) )
          if ( ! visited[w] )
          {
            visit ( w );  visited [w] = true;
            EnQueue ( Q, w );
          }
      }
    }
}
//拓扑排序:可以测试一个有向图是否有环
void Graph::topsort( )
{
    Queue<Vertex> q;
    int counter = 0;
    q.makeEmpty( );
    for each Vertex v
        if( v.indegree == 0 )
            q.enqueue( v );
    while( !q.isEmpty( ) )
    {
        Vertex v = q.dequeue( );
        v.topNum = ++counter;  // Assign next number
        for each Vertex w adjacent to v
            if( --w.indegree == 0 )
                q.enqueue( w );
    }
    if( counter != NUM_VERTICES )
        throw CycleFoundException( );
}
/*迪杰斯特拉算法:
求一个顶点到其他各顶点的最短路径。
算法:
(a) 初始化:用起点v到该顶点w的直接边(弧)初始化最短路径,否则设为∞;
(b) 从未求得最短路径的终点中选择路径长度最小的终点u:即求得v到u的最短路径;
(c) 修改最短路径:计算u的邻接点的最短路径,若(v,…,u)+(u,w)<(v,…,w),则以(v,…,u,w)代替。
(d) 重复(b)-(c),直到求得v到其余所有顶点的最短路径。
特点:总是按照从小到大的顺序求得最短路径。
*/
//单源最短路径dijkstra算法:s点到其他各顶点的最短路径
void Graph::dijkstra( Vertex s )
{
    for each Vertex v
    {
        v.dist = INFINITY;
        v.known = false;
    }
    s.dist = 0;
    for( ; ; )
    {
        Vertex v = smallest unknown distance vertex;
        if( v == NOT_A_VERTEX )
            break;
        v.known = true;
        for each Vertex w adjacent to v
            if( !w.known )
                if( v.dist + cvw < w.dist )
                {
                    // Update w
                    w.dist = v.dist + cvw;
                    w.path = v;
                }
    }
}
//图边的权值为1,最短路径:s点到其他各顶点的最短路径
void Graph::unweighted( Vertex s )
{
    for each Vertex v
    {
        v.dist = INFINITY;
        v.known = false;
    }
    s.dist = 0;
    for( int currDist = 0; currDist < NUM_VERTICES; currDist++ )
        for each Vertex v
            if( !v.known && v.dist == currDist )
            {
                v.known = true;
                for each Vertex w adjacent to v
                    if( w.dist == INFINITY )
                    {
                        w.dist = currDist + 1;
                        w.path = v;
                    }
            }
}
//图边的权值为1,最短路径:s点到其他各顶点的最短路径
void Graph::unweighted( Vertex s )
{
    Queue<Vertex> q;
    for each Vertex v
        v.dist = INFINITY;
    s.dist = 0;
    q.enqueue( s );
    while( !q.isEmpty( ) )
    {
        Vertex v = q.dequeue( );
        for each Vertex w adjacent to v
            if( w.dist == INFINITY )
            {
                w.dist = v.dist + 1;
                w.path = v;
                q.enqueue( w );
            }
    }
}
//有负边值的加权最短路径算法
void Graph::weightedNegative( Vertex s )
{
    Queue<Vertex> q;
    for each Vertex v
        v.dist = INFINITY;
    s.dist = 0;
    q.enqueue( s );
    while( !q.isEmpty( ) )
    {
        Vertex v = q.dequeue( );
        for each Vertex w adjacent to v
            if( v.dist + cvw < w.dist )
            {
                // Update w
                w.dist = v.dist + cvw;
                w.path = v;
                if( w is not already in q )
                    q.enqueue( w );
            }
    }
}
/**
 * Compute all-shortest paths.
 * a contains the adjacency matrix with a[ i ][ i ] presumed to be zero.
 * d contains the values of the shortest path.
 * Vertices are numbered starting at 0; all arrays have equal dimension. 
 * A negative cycle exists if d[ i ][ i ] is set to a negative value.
 * Actual path can be computed using path[ ][ ].
 * NOT_A_VERTEX is -1
 */
void allPairs( const matrix<int> & a, matrix<int> & d, matrix<int> & path ) 
{
    int n = a.numrows( );
    // Initialize d and path
    for( int i = 0; i < n; i++ )
        for( int j = 0; j < n; j++ )
        {
            d[ i ][ j ] = a[ i ][ j ];
            path[ i ][ j ] = NOT_A_VERTEX;
        }
    for( int k = 0; k < n; k++ )
        // Consider each vertex as an intermediate
        for( int i = 0; i < n; i++ )
            for( int j = 0; j < n; j++ )
                if( d[ i ][ k ] + d[ k ][ j ] < d[ i ][ j ] )
                {
                    // Update shortest path
                    d[ i ][ j ] = d[ i ][ k ] + d[ k ][ j ];
                    path[ i ][ j ] = k;
                }
}
    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/luxiaoxun/article/details/7435726
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞