深度优先搜索(DFS)
类似树的前序遍历,规定以某节点为根节点,从根结点出发,在没碰到重复顶点的情况下,遇到分叉路口就始终向右手边走,每路过一个顶点就做一个记号,没无路可走时就回退一步,走另一个分岔路口。
接下来是DFS的递归实现,图的存储结构及创建使用前一篇写过的邻接表。结合上一篇文章的邻接表部分的代码可以实现编译运行。
bool Visited[MAX_VERTEX_NUM]; //为了避免同一顶点被访问多次,设置此标记数组
void DFS(Graph G,int v) //从第v个顶点出发,深度优先遍历图G
{
if(Visited[v]==false) //如果该顶点没有被访问过
{
Visited[v] = true; //标记为访问过
printf("%c",G->vertices[v].data); //输出数据
}
ArcNode *arc;
arc = G->vertices[v].firstarc;//arc保存与此顶点相连的第一条弧
while(arc != NULL) //若刚访问过的顶点 存在 与之相连的边(顶点)
{
if (Visited[arc->adjvex] = false) //若与之相连的顶点没有被访问过
DFS(G,arc->adjvex); //从相连的顶点开始继续递归访问
arc = arc -> nextarc; //arc指向与此边相连的下一条边(下一个顶点)
}
}
void DFS_traverse(Graph G,int t) //给定初始顶点数组序号t,遍历整个图结构
{
for (int v = 0;v<G->vexnum;v++) //Visited数组初始化
Visited[v] = false;
DFS(G,t); //访问初始给定顶点
for(int v = 0;v<G->vexnum;v++) //访问剩余漏下的顶点(其他连通分量)
{
if(Visited[v] == false)
DFS(G,v);
}
}
广度优先搜索(BFS)
类似树的层序遍历,规定以某节点为根节点,从根节点出发,依次访问与此结点相邻的所有结点,然后从这些邻接点出发再依次访问它们的邻接点。需注意:应使“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问。
BFS一般借助队列实现,图结构采用前一篇写过的邻接表,结合之前写过的邻接表和队列的代码,可以使下列程序编译运行。
bool Visited[MAX_VERTEX_NUM]; //为了避免同一顶点被访问多次,设置此标记数组
void BFS_traverse(Graph G,int t) //给定初始顶点数组序号t,遍历整个图结构
{
for (int v = 0;v<G->vexnum;v++) //Visited数组初始化
Visited[v] = false;
SqQueue Q; //建立队列并初始化
InitQueue(Q);
for(int v = 0;v<vexnum;v++)
{
if(Visited[v] == false) //该顶点没有访问过
{
Visited[v] = true; //标志数组置1
printf("%c",G->vertices[v].data); //访问数据
EnQueue(Q,v); //顶点v入队
while(Q.front != Q.rear)//若队列中有元素
{
int temp;
DeQueue(Q,temp); //顶点v出队并将其记录在临时变量temp中
ArcNode *arc;
arc = G->vertices[v].firstarc;//arc保存与此顶点相连的第一条弧
for(int w=arc->adjvex; arc!=null; w=arc->nextarc->adjvex,arc=arc->next)//与v相邻的所有顶点
if(Visited[w]=false) //w为未访问过的相邻顶点,访问这些顶点并使其依次入队
{
Visited[w]=true;
printf("%c",G->vertices[w].data); //访问数据
EnQueue(Q,w);
}
}
}
}
]