void DFS( Graph &G, int v )
{
visit( G, v );
G.Mark[v] = VISITED; //访问当前顶点
for( Edge e = G.FirstEdge(v); G.IsEdge(e); e = G.NextEdge(e) )//遍历当前节点的所有邻接顶点
{
int to_v = G.ToVertices(e); //一个邻接顶点
if( G.Mark[to_v] == UNVISITED ) //如果未被访问,递归访问
{
DFS( G, to_v );
}
}
}
void BFS( Graph &G, int v )
{
queue<int> graphQueue;
visit( G, cur_v );
G.Mark[cur_v] = VISITED; //进队列前访问
graphQueue.enqueue(v); //进入队列
while(!graphQueue.empty())
{
int cur_v = graphQueue.dequeue();
for( Edge e = G.FirstEdge(cur_v); G.IsEdge(e); e = G.NextEdge(e) )//出队列时遍历所有相邻顶点
{
int to_v = G.ToVertices(e); //相邻顶点
if( G.Mark[to_v] == UNVISITED ) //如果未被访问
{
visit( G, to_v );
G.Mark[to_v] = VISITED; //进队列前访问
graphQueue.enqueue(to_v); //进入队列
}
}
}
}
void Dijkstra( Graph &G, int s, Dist* &D )
{
D = new Dist[G.VerticesNum()]; //D数组用于保存最短距离及路径
//存储元素为Dist对象,包含节点的编号、到s的距离、路径前驱节点编号
for(int i=0; i<G.VerticesNum(); i++) //初始化数组D和Mark
{
D[i].index = i;
D[i].length = INFINITY;
D[i].pre = s;
G.Mark[i] = UNVISITED;
}
MinHeap<Dist> H(G.EdgesNum()); //第二组构造为小顶堆
D[s].length = 0;
H.Insert(D[s]); //初始时,源顶点也在第二组
while(1)
{
Dist targ; //targ用于存储目标顶点(第二组中length最小)
bool FOUND = false;
while(!H.isEmpty()) //寻找目标顶点
{
targ = H.RemoveTop();
if( G.Mark[targ.index] == UNVISITED ) //判断是否访问过
{
FOUND = true;
break;
}
}
if( false == FOUND )
break;
int v = targ.index;
G.Mark[v] = VISITED; //目标顶点放入第一组(已访问)
for( Edge e = G.FirstEdge(v); G.IsEdge(e); e = G.NextEdge(e) ) //遍历目标顶点的所有邻接顶点
{
int to_v = G.ToVertices(e); //一个邻接顶点
if( D[to_v].length > ( D[v].length + G.Weight(e) )) //对邻接顶点的距离进行一次修正
{
D[to_v].length = D[v].length + G.Weight(e);
D[to_v].pre = v; //设置顶点的前驱
H.Insert(D[to_v]); //由于修正距离而重新进堆的顶点
//最终会被VISITED标识剔除
}
}
}
}