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