图的数据结构不像二叉树那样,有明显的父子节点和兄弟节点的关系,它只有一个关系就是邻接关系。故对图中顶点的访问要采用标志数组(来确定改结点是否被访问,去除重复访问)。并且对图的深度遍历采用递归的方式是较高效的。
1.深度遍历(DFS)
#include<iostream>
#include<stdlib.h>
using namespace std;
//DFS
#define MAX 10
bool visited[MAX];
status (*VisitFunc)(int v);//定义函数指针
void DFS(Graph G,int v)
{
visited[v]=TRUE;VisitFunc(v);
for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w))
if(!visited[w]) DFS(G,w);//与树的DFS的区别
}
void DFSt(Graph G,status(*Visit)(int v))
{
VisitFunc = Visit;//为函数指针赋值
for(v=0;v<G.vexnum;++v) visited[v]=FALSE;//初始化标志数组
//memset(visited,0,sizeof(visited));
for(v=0;v<G.vexnum;++v)
if(!visited[v])DFS(G,v);
}
2.广度遍历(BFS)
广度优先遍历利用辅助队列后,很好的达到了遍历的效果。
#include<iostream>
#include<stdlib.h>
using namespace std;
//BFS
#define MAX 10
bool visited[MAX];
status (*VisitFunc)(int v);//定义函数指针
void BSF(Graph G,Status(* Visit)(int v))
{
for(v=0;v<G.vexnum;++v) visited[v]=FALSE;
InitQueue(Q);
for(v=0;v<G.vexnum;++v)
{
if(!visited[v])
{
visited[v]=TRUE;Visit(v);
EnQueue(Q,v);
while(!QueueEmpty(Q))
{
DeQueue(Q,u);
for(w=FirstAdjVex(G,u);w>=0;w=NextAdjVex(G,u,w))
{
if(!Visited[w])
{
Visited[w]=TRUE;Visit(w);
EnQueue(Q,w);//把节点的所有邻接节点都入队,并且都遍历一次
}
}
}
}
}
}
3.总结
对于图结构,若采用邻接表存储的话,FirstAdjVex和NextAdjVex是很好得到的