广度优先遍历

图的遍历

给定一个图G=(V,E)和V(G)中的任一顶点v,从v出发,顺着G的边访问G中的所有顶点,且每个顶点仅被访问一次,这一过程称为遍历图。

一般设置一个辅助数组visited[],用来标记顶点是否被访问过,初始状态为0,访问过则设置为1。

广度优先遍历

  1. #include <stdio.h>
  2. #include <malloc.h>
  3. #include <string.h>
  4. #define MAXVEX 100
  5. typedef char VertexType[3]; /*定义VertexType为char数组类型*/
  6. typedef struct vertex
  7. {
  8. int adjvex; /*顶点编号*/
  9. VertexType data; /*顶点的信息*/
  10. } VType; /*顶点类型*/
  11. typedef struct graph
  12. {
  13. int n,e; /*n为实际顶点数,e为实际边数*/
  14. VType vexs[MAXVEX]; /*顶点集合*/
  15. int edges[MAXVEX][MAXVEX]; /*边的集合*/
  16. } AdjMatix; /*图的邻接矩阵类型*/
  17. typedef struct edgenode
  18. {
  19. int adjvex; /*邻接点序号*/
  20. int value; /*边的权值*/
  21. struct edgenode *next; /*下一条边的顶点*/
  22. } ArcNode; /*每个顶点建立的单链表中结点的类型*/
  23. typedef struct vexnode
  24. {
  25. VertexType data; /*结点信息*/
  26. ArcNode *firstarc; /*指向第一条边结点*/
  27. } VHeadNode; /*单链表的头结点类型*/
  28. typedef struct
  29. {
  30. int n,e; /*n为实际顶点数,e为实际边数*/
  31. VHeadNode adjlist[MAXVEX]; /*单链表头结点数组*/
  32. } AdjList; /*图的邻接表类型*/
  33. void DispAdjList(AdjList *G)
  34. {
  35. int i;
  36. ArcNode *p;
  37. printf("图的邻接表表示如下:\n");
  38. for (i=0;i<G->n;i++)
  39. {
  40. printf(" [%d,%3s]=>",i,G->adjlist[i].data);
  41. p=G->adjlist[i].firstarc;
  42. while (p!=NULL)
  43. {
  44. printf("(%d,%d)->",p->adjvex,p->value);
  45. p=p->next;
  46. }
  47. printf("∧\n");
  48. }
  49. }
  50. void MatToList(AdjMatix g,AdjList *&G) /*例6.3算法:将邻接矩阵g转换成邻接表G*/
  51. {
  52. int i,j;
  53. ArcNode *p;
  54. G=(AdjList *)malloc(sizeof(AdjList));
  55. for (i=0;i<g.n;i++) /*给邻接表中所有头结点的指针域置初值*/
  56. {
  57. G->adjlist[i].firstarc=NULL;
  58. strcpy(G->adjlist[i].data,g.vexs[i].data);
  59. }
  60. for (i=0;i<g.n;i++) /*检查邻接矩阵中每个元素*/
  61. for (j=g.n-1;j>=0;j--)
  62. if (g.edges[i][j]!=0) /*邻接矩阵的当前元素不为0*/
  63. {
  64. p=(ArcNode *)malloc(sizeof(ArcNode));/*创建一个结点*p*/
  65. p->value=g.edges[i][j];p->adjvex=j;
  66. p->next=G->adjlist[i].firstarc; /*将*p链到链表后*/
  67. G->adjlist[i].firstarc=p;
  68. }
  69. G->n=g.n;G->e=g.e;
  70. }
  71. void BFS(AdjList *G,int vi) /*对邻接表g从顶点vi开始进行广宽优先遍历*/
  72. {
  73. int i,v,visited[MAXVEX];
  74. int Qu[MAXVEX],front=0,rear=0; /*循环队列*/
  75. ArcNode *p;
  76. for (i=0;i<G->n;i++) /*给visited数组置初值0*/
  77. visited[i]=0;
  78. printf("%d ",vi); /*访问初始顶点*/
  79. visited[vi]=1; /*置已访问标识*/
  80. rear=(rear=1)%MAXVEX; /*循环移动队尾指针*/
  81. Qu[rear]=vi; /*初始顶点进队*/
  82. while (front!=rear) /*队列不为空时循环*/
  83. {
  84. front=(front+1) % MAXVEX;
  85. v=Qu[front]; /*顶点v出队*/
  86. p=G->adjlist[v].firstarc; /*找v的第一个邻接点*/
  87. while (p!=NULL) /*找v的所有邻接点*/
  88. {
  89. if (visited[p->adjvex]==0) /*未访问过则访问之*/
  90. {
  91. visited[p->adjvex]=1; /*置已访问标识*/
  92. printf("%d ",p->adjvex);/*访问该点并使之入队列*/
  93. rear=(rear+1) % MAXVEX; /*循环移动队尾指针*/
  94. Qu[rear]=p->adjvex; /*顶点p->adjvex进队*/
  95. }
  96. p=p->next; /*找v的下一个邻接点*/
  97. }
  98. }
  99. }
  100. void main()
  101. {
  102. int i,j;
  103. AdjMatix g;
  104. AdjList *G;
  105. int a[5][5]={ {0,1,0,1,0},{1,0,1,0,0},{0,1,0,1,1},{1,0,1,0,1},{0,0,1,1,0} };
  106. char *vname[MAXVEX]={"a","b","c","d","e"};
  107. g.n=5;g.e=12; /*建立图6.1(a)的无向图,每1条无向边算为2条有向边*/
  108. for (i=0;i<g.n;i++)
  109. strcpy(g.vexs[i].data,vname[i]);
  110. for (i=0;i<g.n;i++)
  111. for (j=0;j<g.n;j++)
  112. g.edges[i][j]=a[i][j];
  113. MatToList(g,G); /*生成邻接表*/
  114. DispAdjList(G); /*输出邻接表*/
  115. printf("从顶点0的广度优先遍历序列:\n");
  116. printf("\t");BFS(G,0);printf("\n");
  117. }