首先这里的操作都是基于邻接矩阵的。
深度优先遍历的过程是
- 首先从一个顶点V开始,输出当前的顶点。
- 从当前顶点的一个邻接顶点开始,继续深度优先遍历。当然要排除掉已经遍历过的点。
- 当前顶点的邻接顶点前全部遍历一遍
void DfsMgraph(const Mgraph* G,int i,bool * const visited)
{
visited[i]=true;
printf("%2c",G->vexs[i]);
for (int j=0;j<G->numVertexs;j++)
{
if (G->arc[i][j]==1&&!visited[j])
DfsMgraph(G,j,visited);
}
}
这样在执行完这个过程后,所有与开始顶点相连通的点都会遍历一遍。
如果图中图中那个的顶点并不是全部连通的呢,没关系,只要我们把每个顶点都用DFS遍历一遍即可。
代码中数组visited[k]来标记编号为k顶点是否被访问过。
void DfsTraverseMgraph(Mgraph* G)
{
bool *visited=(bool*)malloc(sizeof(bool)*G->numVertexs);
int i;
for (i=0;i<G->numVertexs;i++)
visited[i]=false;
for (i=0;i<G->numVertexs;i++)
if (!visited[i])
DfsMgraph(G,i,visited);
printf("\n邻接矩阵深度优先遍历完成\n");
}
那么广度优先遍历呢,
- 首先遍历当前节点,然后遍历当前节点的领结顶点。
- 从当前节点的某个领结顶点开始,广度优先遍历所有的领结顶点。
代码需要借助一个队列来实现:
void BfsTraverseMgraph(Mgraph *G)
{
bool *visited=(bool*)malloc(sizeof(bool)*G->numVertexs);
if (!visited)
exit(-1);
int i,j,k;
for (i=0;i<G->numVertexs;i++)
visited[i]=false;
Queue *Q=CreatQueue();//创建队列
for (i=0;i<G->numVertexs;i++)
{
if (visited[i])
continue;
visited[i]=true;
printf("%2c",G->vexs[i]);
EnQueue(Q,i);//当前顶点入队
while (!EmptyQueue(Q))//队列中有顶点存在
{
DeQueue(Q,k);//出队,遍历出队顶点的领结顶点
for (j=0;j<G->numVertexs;j++)
{
if (G->arc[k][j]==1&&!visited[j])
{
visited[j]=true;
printf("%2c",G->vexs[j]);
EnQueue(Q,j);//刚刚遍历的邻接顶点入队,
}
}
}//重复,直到队列中没有顶点,即所有最初顶点连通的顶点都遍历玩
}
printf("\n邻接矩阵广度遍历完成\n");
}
面试的时候,有一个朋友圈的问题,其实就是判断图中有多少个连通域,可以用遍历的思想解决,加个简单的printf("\n"),即可