(C/C++)-图的深度优先遍历(DFS)和广度优先遍历(BFS)

傷城~ 2023-01-03 01:54 360阅读 0赞

(C/C++)-图的深度优先遍历(DFS)和广度优先遍历(BFS)

1、图的深度优先遍历(DFS)

图的深度优先遍历与树的先序遍历类似,即尽可能深的遍历图

这里采取邻接矩阵存储图,存储的图如下:
在这里插入图片描述
ps: 这个图沿用我的上一篇文章(最小生成树和单源最短路径),有兴趣的伙伴可以看看——点击传送门

基本思想:

  • 先访问图的某一顶点v,然后由顶点v出发,访问与顶点v邻接并且未被访问的任一顶点w1;
  • 在由w1出发,访问与顶点w1邻接并且未被访问的任一顶点w2;
  • 重复上述过程,直到所有顶点被访问;

具体实现:

图遍历所需的基本函数:

  1. int visited[N] = {
  2. 0};//标记顶点是否被访问,初始为0
  3. int s[N] = {
  4. 0 };//标记顶点是否被访问,初始为0(NextNeighbor():这里用辅助数组s[i],防止无限套娃-_-)
  5. //返回图G中顶点v的一个邻接顶点,若不存在则返回-1
  6. int FirstNeighbor(int G[N][N], int v)
  7. {
  8. int i;
  9. for (i = 1; i < N; i++)
  10. if (G[v][i] != maxint)
  11. return i;
  12. return -1;
  13. }
  14. //返回图G中顶点v的一个不是w的邻接顶点,若不存在则返回-1
  15. int NextNeighbor(int G[N][N], int v, int w)
  16. {
  17. int i;
  18. for (i = 1; i < N; i++)
  19. if (G[v][i] != maxint && i != w && !s[i])//这里用辅助数组s[i],防止无限套娃-_-
  20. {
  21. s[i] = 1;
  22. return i;
  23. }
  24. return -1;
  25. }

深度优先遍历过程:

  1. //从顶点v开始做深度优先遍历
  2. void DFS(int G[N][N], int v)
  3. {
  4. printf("%d ", v);//先访问顶点v
  5. visited[v] = 1;//标记顶点v已经访问
  6. //深度优先遍历
  7. for (int w = FirstNeighbor(G, v); w >= 1; w = NextNeighbor(G, v, w))
  8. if (!visited[w])
  9. DFS(G, w);
  10. }
  11. //从每个顶点进行深度优先遍历,防止非连通图
  12. void DFSTraverse(int G[N][N])
  13. {
  14. for (int v = 1; v < N; v++)
  15. if (!visited[v])
  16. DFS(G, v);
  17. }

接下来在main()函数中测试一下

  1. int main()
  2. {
  3. int G[N][N] = {
  4. {
  5. 0},//0号下标不使用
  6. {
  7. 0,maxint,10,maxint,maxint,5},
  8. {
  9. 0,maxint,maxint,1,maxint,2},
  10. {
  11. 0,maxint,maxint,maxint,4,maxint},
  12. {
  13. 0,7,maxint,6,maxint,maxint},
  14. {
  15. 0,maxint,3,9,2,maxint}
  16. };//5个顶点,0号下标不使用
  17. DFSTraverse(G);
  18. return 0;
  19. }

在这里插入图片描述


2、图的广度优先遍历(BFS)

图的广度优先遍历与树的层次遍历类似,需要借助队列来实现

ps:沿用上图

基本思想:

  • 首先访问某一顶点v,并由v出发,依次访问顶点v未被访问过的所有邻接顶点w1,w2…wi;
  • 再依次访问w1,w2…wi未被访问过的所有邻接顶点;
  • 重复上述过程,直到所有顶点被访问;

具体实现:

  1. //从顶点v开始做广度优先遍历
  2. void BFS(int G[N][N], int v)
  3. {
  4. printf("%d ", v);//访问顶点v
  5. visited[v] = 1;//标记顶点v已经访问
  6. //广度优先遍历(类似二叉树层次遍历)
  7. que.push(v);
  8. while (!que.empty())
  9. {
  10. v = que.front();
  11. que.pop();//出队
  12. for (int w = FirstNeighbor(G, v); w >= 1; w = NextNeighbor(G, v, w))
  13. if (!visited[w])
  14. {
  15. printf("%d ", w);//访问顶点w
  16. visited[w] = 1;
  17. que.push(w);
  18. }
  19. }
  20. }
  21. //从每个顶点进行广度优先遍历,防止非连通图
  22. void BFSTraverse(int G[N][N])
  23. {
  24. for (int v = 1; v < N; v++)
  25. if (!visited[v])
  26. BFS(G, v);
  27. }

在main()中测试:

  1. int main()
  2. {
  3. int G[N][N] = {
  4. {
  5. 0},//0号下标不使用
  6. {
  7. 0,maxint,10,maxint,maxint,5},
  8. {
  9. 0,maxint,maxint,1,maxint,2},
  10. {
  11. 0,maxint,maxint,maxint,4,maxint},
  12. {
  13. 0,7,maxint,6,maxint,maxint},
  14. {
  15. 0,maxint,3,9,2,maxint}
  16. };//5个顶点,0号下标不使用
  17. BFSTraverse(G);
  18. return 0;
  19. }

在这里插入图片描述


图的两种遍历方式学习到这里就结束了:)

发表评论

表情:
评论列表 (有 0 条评论,360人围观)

还没有评论,来说两句吧...

相关阅读