1. /*
    2. 在采用邻接表存储的图上进行广度优先遍历/深度优先遍历
    3. 分析:我们知道邻接表上的顶点所连接的节点都是它的相邻节点,而对于广度优先遍历来说,类似于层次遍历,就是要把所有的邻接点进行访问,
    4. 所以我们需要从第一个节点开始访问它的所有邻接点,还有需要注意的是,当我们把邻接点访问后,需要依次访问邻接点的邻接点,这就需要
    5. 用队列将我们访问过得邻接点入队,这和层次遍历一样,也只有这样,我们才能访问所有的节点。当然,在这个过程中,会有重复访问的情况,
    6. 所以我们需要用一个数组来记录节点的访问情况,已访问置true
    7. 对于深度优先遍历,顾名思义,我们会把每一个节点“榨干”,“顺藤摸瓜”,同样我们需要一个访问标记数组,而对于深度优先遍历,
    8. 我们将采用递归的方式来进行。
    9. */
    10. //创建邻接表图结构 分为边表节点结构 顶点表节点结构 图结构
    11. #define MAXSIZE 100
    12. #define TYPE int
    13. //边表结构
    14. typedef struct EdgeNode {//边表结点
    15. int index;//该边所指向的顶点的位置,在顶点数组里面的位置信息
    16. int weight;//权值
    17. EdgeNode *next;//下一个邻接边
    18. }EdgeNode;
    19. typedef struct VertexNode {//顶点表节点
    20. int info;//顶点信息
    21. EdgeNode *firstEdge;//指向第一条依附该顶点的边的指针
    22. }VertexNode, Adjlist[MAXSIZE];
    23. typedef struct {
    24. Adjlist adjlist;//顶点数组
    25. int numE, numV;//边数、顶点数
    26. }ALGraph;
    27. //队列结构(我们采用顺序队列)
    28. struct Squeue {
    29. TYPE *arr;
    30. int front, rear;
    31. };
    32. #include <stdio.h>
    33. #include <stdlib.h>
    34. void BFSBegin(ALGraph *G) {
    35. void BFS(ALGraph *, int *, int);
    36. int *visited = (int *)malloc(sizeof(int)*G->numV);//设置标记数组
    37. for (int i = 0; i < G->numV; i++) {
    38. visited[i] = 0;
    39. }
    40. for (int i = 1; i < G->numV; i++) {//从第一个节点开始
    41. if (!visited[i]) {
    42. BFS(G, visited, i);
    43. }
    44. }
    45. }
    46. void BFS(ALGraph *G, int *visited, int v) {//开始广度遍历
    47. //声明有关队列的函数
    48. Squeue *createQueue(int);
    49. bool isEmpty(Squeue *);
    50. bool enQueue(Squeue *, TYPE, int);
    51. bool deQueue(Squeue *sq, TYPE *data, int maxSize);
    52. Squeue *sq;
    53. sq = createQueue(G->numV);//创建队列
    54. printf("%c ", G->adjlist[v].info);//访问传进来的顶点
    55. enQueue(sq, v, G->numV);//入队
    56. visited[v] = 1;//置为已访问
    57. while (!isEmpty(sq)) {//队列不空,取出队首元素,进行访问
    58. TYPE top;
    59. deQueue(sq, &top, G->numV);
    60. for (EdgeNode *w = G->adjlist[top].firstEdge; w; w = w->next) {//依次将当前节点的边表入队,和层次遍历一致
    61. if (!visited[w->index]) {
    62. printf("%c ", G->adjlist[w->index].info);
    63. visited[w->index] = 1;
    64. enQueue(sq, w->index, G->numV);
    65. }
    66. }
    67. }
    68. }
    69. void DFSBegin(ALGraph *G) {
    70. void DFS(ALGraph *, int *, VertexNode *, int);
    71. int *visited = (int *)malloc(sizeof(int)*G->numV);//设置标记数组
    72. for (int i = 0; i < G->numV; i++) {
    73. visited[i] = 0;
    74. }
    75. for (int i = 0; i < G->numV; i++) {//从第一个节点开始“顺藤摸瓜”
    76. if (!visited[i]) {
    77. DFS(G, visited, &G->adjlist[i], i);
    78. }
    79. }
    80. }
    81. void DFS(ALGraph *G, int *visited, VertexNode *v, int index) {
    82. printf("%c ", v->info);//打印传入的节点
    83. visited[index] = 1;//置访问为1
    84. for (EdgeNode *w = v->firstEdge; w; w = w->next) {
    85. if (w) {//如果有邻接点,传入DFS
    86. if (!visited[w->index]) {//未访问
    87. DFS(G, visited, &G->adjlist[w->index], w->index);
    88. }
    89. }
    90. }
    91. }
    92. int main() {
    93. ALGraph *graph = (ALGraph *)malloc(sizeof(ALGraph *));
    94. //声明函数
    95. void createGraph(ALGraph *);
    96. void createGraphInFile(ALGraph *);
    97. void dispGraph(ALGraph *);
    98. //创建图
    99. createGraphInFile(graph);
    100. //打印图
    101. dispGraph(graph);
    102. //广度优先遍历
    103. //BFSBegin(graph);
    104. //深度优先遍历
    105. DFSBegin(graph);
    106. return 0;
    107. }