您的位置:首页 > 其它

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

2012-04-07 18:17 330 查看
//深度优先遍历:
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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐