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

来源:互联网 发布:软件开发系统学习 编辑:程序博客网 时间:2024/05/07 14:34

复制代码
//深度优先遍历:   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;                  }  }  
复制代码

 

作者:阿凡卢
出处:http://www.cnblogs.com/luxiaoxun/
0 0
原创粉丝点击