利用邻接表实现图的广度优先遍历,使用c语言
时间: 2024-02-09 22:10:52 浏览: 69
好的,下面给出使用邻接表实现图的广度优先遍历的C语言代码:
```
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX_NUM 20 // 最大顶点数
// 定义邻接表中每个节点的结构体
typedef struct ArcNode {
int adjvex; // 邻接点在图中的位置
struct ArcNode *nextarc; // 指向下一个邻接点的指针
} ArcNode;
// 定义邻接表中每个头节点的结构体
typedef struct VNode {
int data; // 顶点的数据
ArcNode *firstarc; // 指向第一个邻接点的指针
} VNode;
// 定义图的结构体
typedef struct {
VNode vertex[MAX_VERTEX_NUM]; // 顶点数组
int vexnum; // 顶点数
} Graph;
// 初始化图
void initGraph(Graph *G, int n) {
G->vexnum = n;
for(int i = 0; i < n; i++) {
G->vertex[i].data = i;
G->vertex[i].firstarc = NULL;
}
}
// 添加边
void addEdge(Graph *G, int i, int j) {
ArcNode *node = (ArcNode*)malloc(sizeof(ArcNode));
node->adjvex = j;
node->nextarc = G->vertex[i].firstarc;
G->vertex[i].firstarc = node;
}
// 广度优先遍历
void BFS(Graph *G, int i, int *visited) {
int queue[MAX_VERTEX_NUM], front = 0, rear = 0; // 定义队列
visited[i] = 1; // 标记该节点已被访问
printf("%d ", G->vertex[i].data);
queue[rear++] = i; // 将该节点入队
while(front != rear) { // 当队列不为空时
int j = queue[front++]; // 取出队首元素
ArcNode *p = G->vertex[j].firstarc;
while(p != NULL) { // 遍历该节点的所有邻接点
int k = p->adjvex;
if(!visited[k]) { // 如果该邻接点未被访问,则标记该节点已被访问、输出该节点的数据,并将该节点入队
visited[k] = 1;
printf("%d ", G->vertex[k].data);
queue[rear++] = k;
}
p = p->nextarc;
}
}
}
// 对图进行广度优先遍历
void BFSTraverse(Graph *G) {
int visited[MAX_VERTEX_NUM] = {0}; // 初始所有节点都未被访问
for(int i = 0; i < G->vexnum; i++) {
if(!visited[i]) { // 如果该节点未被访问,则从该节点开始进行广度优先遍历
BFS(G, i, visited);
}
}
}
// 测试
int main() {
Graph G;
initGraph(&G, 5);
addEdge(&G, 0, 1);
addEdge(&G, 0, 2);
addEdge(&G, 1, 2);
addEdge(&G, 2, 0);
addEdge(&G, 2, 3);
addEdge(&G, 3, 3);
printf("广度优先遍历结果:");
BFSTraverse(&G);
printf("\n");
return 0;
}
```
上述代码中,我们使用了邻接表来表示图,每个节点包含了一个顶点的数据和一个指向该顶点的第一个邻接点的指针。在添加边时,我们将邻接点添加到该顶点的邻接表中,并将其作为第一个邻接点。在广度优先遍历时,我们使用一个队列来存储已经访问过但未被遍历的节点,初始时,将起始节点标记为已被访问,并将其入队。然后,我们从队首开始遍历队列中的所有节点,将其所有未被访问的邻接点标记为已被访问、输出其数据,并将其入队。最后,我们对所有未被访问的节点进行广度优先遍历,直到所有节点都被访问为止。
阅读全文