1. #include "stdio.h"
    2. #include "stdlib.h"
    3. #include "io.h"
    4. #include "math.h"
    5. #include "time.h"
    6. #define OK 1
    7. #define ERROR 0
    8. #define TRUE 1
    9. #define FALSE 0
    10. typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
    11. typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
    12. typedef char VertexType; /* 顶点类型应由用户定义 */
    13. typedef int EdgeType; /* 边上的权值类型应由用户定义 */
    14. #define MAXSIZE 9 /* 存储空间初始分配量 */
    15. #define MAXEDGE 15
    16. #define MAXVEX 9
    17. #define INFINITY 65535
    18. typedef struct
    19. {
    20. VertexType vexs[MAXVEX]; /* 顶点表 */
    21. EdgeType arc[MAXVEX][MAXVEX];/* 邻接矩阵,可看作边表 */
    22. int numVertexes, numEdges; /* 图中当前的顶点数和边数 */
    23. }MGraph;
    24. /* 用到的队列结构与函数********************************** */
    25. /* 循环队列的顺序存储结构 */
    26. typedef struct
    27. {
    28. int data[MAXSIZE];
    29. int front; /* 头指针 */
    30. int rear; /* 尾指针,若队列不空,指向队列尾元素的下一个位置 */
    31. }Queue;
    32. /* 初始化一个空队列Q */
    33. Status InitQueue(Queue *Q)
    34. {
    35. Q->front=0;
    36. Q->rear=0;
    37. return OK;
    38. }
    39. /* 若队列Q为空队列,则返回TRUE,否则返回FALSE */
    40. Status QueueEmpty(Queue Q)
    41. {
    42. if(Q.front==Q.rear) /* 队列空的标志 */
    43. return TRUE;
    44. else
    45. return FALSE;
    46. }
    47. /* 若队列未满,则插入元素e为Q新的队尾元素 */
    48. Status EnQueue(Queue *Q,int e)
    49. {
    50. if ((Q->rear+1)%MAXSIZE == Q->front) /* 队列满的判断 */
    51. return ERROR;
    52. Q->data[Q->rear]=e; /* 将元素e赋值给队尾 */
    53. Q->rear=(Q->rear+1)%MAXSIZE;/* rear指针向后移一位置, */
    54. /* 若到最后则转到数组头部 */
    55. return OK;
    56. }
    57. /* 若队列不空,则删除Q中队头元素,用e返回其值 */
    58. Status DeQueue(Queue *Q,int *e)
    59. {
    60. if (Q->front == Q->rear) /* 队列空的判断 */
    61. return ERROR;
    62. *e=Q->data[Q->front]; /* 将队头元素赋值给e */
    63. Q->front=(Q->front+1)%MAXSIZE; /* front指针向后移一位置, */
    64. /* 若到最后则转到数组头部 */
    65. return OK;
    66. }
    67. /* ****************************************************** */
    68. void CreateMGraph(MGraph *G)
    69. {
    70. int i, j;
    71. G->numEdges=15;
    72. G->numVertexes=9;
    73. /* 读入顶点信息,建立顶点表 */
    74. G->vexs[0]='A';
    75. G->vexs[1]='B';
    76. G->vexs[2]='C';
    77. G->vexs[3]='D';
    78. G->vexs[4]='E';
    79. G->vexs[5]='F';
    80. G->vexs[6]='G';
    81. G->vexs[7]='H';
    82. G->vexs[8]='I';
    83. for (i = 0; i < G->numVertexes; i++)/* 初始化图 */
    84. {
    85. for ( j = 0; j < G->numVertexes; j++)
    86. {
    87. G->arc[i][j]=0;
    88. }
    89. }
    90. G->arc[0][1]=1;
    91. G->arc[0][5]=1;
    92. G->arc[1][2]=1;
    93. G->arc[1][8]=1;
    94. G->arc[1][6]=1;
    95. G->arc[2][3]=1;
    96. G->arc[2][8]=1;
    97. G->arc[3][4]=1;
    98. G->arc[3][7]=1;
    99. G->arc[3][6]=1;
    100. G->arc[3][8]=1;
    101. G->arc[4][5]=1;
    102. G->arc[4][7]=1;
    103. G->arc[5][6]=1;
    104. G->arc[6][7]=1;
    105. for(i = 0; i < G->numVertexes; i++)
    106. {
    107. for(j = i; j < G->numVertexes; j++)
    108. {
    109. G->arc[j][i] =G->arc[i][j];
    110. }
    111. }
    112. }
    113. Boolean visited[MAXVEX]; /* 访问标志的数组 */
    114. /* 邻接矩阵的深度优先递归算法 */
    115. void DFS(MGraph G, int i)
    116. {
    117. int j;
    118. visited[i] = TRUE;
    119. printf("%c ", G.vexs[i]);/* 打印顶点,也可以其它操作 */
    120. for(j = 0; j < G.numVertexes; j++)
    121. if(G.arc[i][j] == 1 && !visited[j])
    122. DFS(G, j);/* 对为访问的邻接顶点递归调用 */
    123. }
    124. /* 邻接矩阵的深度遍历操作 */
    125. void DFSTraverse(MGraph G)
    126. {
    127. int i;
    128. for(i = 0; i < G.numVertexes; i++)
    129. visited[i] = FALSE; /* 初始所有顶点状态都是未访问过状态 */
    130. for(i = 0; i < G.numVertexes; i++)
    131. if(!visited[i]) /* 对未访问过的顶点调用DFS,若是连通图,只会执行一次 */
    132. DFS(G, i);
    133. }
    134. /* 邻接矩阵的广度遍历算法 */
    135. void BFSTraverse(MGraph G)
    136. {
    137. int i, j;
    138. Queue Q;
    139. for(i = 0; i < G.numVertexes; i++)
    140. visited[i] = FALSE;
    141. InitQueue(&Q); /* 初始化一辅助用的队列 */
    142. for(i = 0; i < G.numVertexes; i++) /* 对每一个顶点做循环 */
    143. {
    144. if (!visited[i]) /* 若是未访问过就处理 */
    145. {
    146. visited[i]=TRUE; /* 设置当前顶点访问过 */
    147. printf("%c ", G.vexs[i]);/* 打印顶点,也可以其它操作 */
    148. EnQueue(&Q,i); /* 将此顶点入队列 */
    149. while(!QueueEmpty(Q)) /* 若当前队列不为空 */
    150. {
    151. DeQueue(&Q,&i); /* 将队对元素出队列,赋值给i */
    152. for(j=0;j<G.numVertexes;j++)
    153. {
    154. /* 判断其它顶点若与当前顶点存在边且未访问过 */
    155. if(G.arc[i][j] == 1 && !visited[j])
    156. {
    157. visited[j]=TRUE; /* 将找到的此顶点标记为已访问 */
    158. printf("%c ", G.vexs[j]); /* 打印顶点 */
    159. EnQueue(&Q,j); /* 将找到的此顶点入队列 */
    160. }
    161. }
    162. }
    163. }
    164. }
    165. }
    166. int main(void)
    167. {
    168. MGraph G;
    169. CreateMGraph(&G);
    170. printf("\n深度遍历:");
    171. DFSTraverse(G);
    172. printf("\n广度遍历:");
    173. BFSTraverse(G);
    174. return 0;
    175. }