找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 3947|回复: 0

图的广度优先搜索(邻接表)

[复制链接]
发表于 2012-2-11 19:50:09 | 显示全部楼层 |阅读模式

图的遍历(Traversing Graph)是指从图中某一顶点出发访问图中其余顶点,且使每个顶点仅被访问一次。

广度优先搜索(Breadth First Search)

       广度优先搜索假设从图中某个顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,然后再分别从这些邻接点出发依次访问它们的邻接点,并使先被访问的顶点的邻接点先于后被访问的顶点的邻接点被访问(因此需要用队列来存储顶点),直到图中所有已被访问的顶点的邻接点都被访问为止。如果此时图中还有未被访问的顶点,则另选图中未被访问的顶点作为起点,重复上述过程,直到图中所有顶点都被访问为止。

采用邻接表存储图的具体实现如下:#include <iostream>

  1. #include <queue>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. using namespace std;
  5. #define VERTEXNUM 100 //顶点个数
  6. typedef char VertexType;
  7. typedef int EdgeType;
  8. typedef enum{FALSE, TRUE} Boolean;
  9. Boolean visited[VERTEXNUM];
  10. /***************************************
  11. *
  12. * 邻接表存储结构
  13. *
  14. * *************************************/
  15. typedef struct node
  16. {
  17.         int adjvex; //顶点位置
  18.         struct node *next; //指向下一条边的指针
  19. }EdgeNode;
  20. typedef struct vnode
  21. {
  22.         VertexType vertex; //顶点信息
  23.         EdgeNode *firstedge; //指向第一条依附该顶点的边的指针
  24. }AdjList[VERTEXNUM];
  25. typedef struct
  26. {
  27.         AdjList vertexs; //邻接表
  28.         int vernum, edgenum; //图中当前的顶点和边数
  29. }Graph;
  30. /***************************************
  31. *
  32. * 建立图的邻接表
  33. *
  34. * *************************************/
  35. void MakeGraph(Graph *graph)
  36. {
  37.         int v1, v2;
  38.         int i, j, k;
  39.         printf("请输入图的顶点数n和边数e:\n");
  40.         scanf("%d%d", &graph->vernum, &graph->edgenum);
  41.         printf("请输入顶点信息(顶点号<CR>)每个顶点以回车作为结束:\n");
  42.         for(i = 0; i < graph->vernum; i++)
  43.         {
  44.                 getchar();
  45.                 scanf("%c", &graph->vertexs[i].vertex);
  46.                 graph->vertexs[i].firstedge = NULL; //初始第一条边为空
  47.         }
  48.         printf("请输入每条边对应的两个顶点的序号(格式为i,j):\n");
  49.         EdgeNode *p;
  50.         for(k = 0; k < graph->edgenum; k++)
  51.         {
  52.                 scanf("%d,%d", &i, &j);  //读入边<vi,vj>的序号
  53.                 p = (node *)malloc(sizeof(node)); //生成新的结点
  54.                 p->adjvex = j - 1;
  55.                 p->next = graph->vertexs[i - 1].firstedge;
  56.                 graph->vertexs[i - 1].firstedge = p;
  57.         }
  58. }
  59. /***************************************
  60. *
  61. * 广度优先遍历
  62. *
  63. * *************************************/
  64. void BFS(Graph *graph)
  65. {
  66.         int i, j, k;
  67.         queue<int> q;
  68.         EdgeNode *p;
  69.         for(i = 0; i < graph->vernum; i++) //初始化访问标识数组
  70.                 visited[i] = FALSE;
  71.         for(i = 0; i < graph->vernum; i++)
  72.         {
  73.                 if(!visited[i])
  74.                 {
  75.                         visited[i] = TRUE;
  76.                         printf("广度优先遍历:结点%c\n", graph->vertexs[i].vertex);
  77.                         q.push(i); //入栈
  78.                         while(!q.empty())
  79.                         {
  80.                                 j = q.front();
  81.                                 q.pop();  //出栈
  82.                                 p = graph->vertexs[j].firstedge;
  83.                                 while(p)
  84.                                 {
  85.                                         if(!visited[p->adjvex])
  86.                                         {
  87.                                                 printf("广度优先遍历:结点%c\n", graph->vertexs[p->adjvex].vertex);
  88.                                                 visited[p->adjvex] = TRUE;
  89.                                                 q.push(p->adjvex);
  90.                                         }
  91.                                         p = p->next;
  92.                                 }
  93.                         }
  94.                 }
  95.         }
  96. }
  97. int main()
  98. {
  99.         Graph *graph = (Graph *)malloc(sizeof(Graph));
  100.         MakeGraph(graph); //建立图的邻接表
  101.         BFS(graph); //广度优先遍历
  102.         return 0;
  103. }
复制代码
图一中的图,运行上述程序得到的结果如图二。


图一


您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-11-23 16:15 , Processed in 0.015020 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表