c语言基于邻接表存储有向图的广度优先遍历
时间: 2023-10-08 07:10:57 浏览: 100
邻接表表示的图的广度优先遍历
好的,我来回答你的问题。
邻接表是一种表示图的数据结构,可以用来存储有向图。广度优先遍历是一种遍历图的算法,可以按照层次顺序依次访问图中的所有节点。
具体来说,基于邻接表存储有向图的广度优先遍历可以按照以下步骤进行:
1. 定义一个队列,用于存储待访问的节点。
2. 将起点节点入队。
3. 当队列不为空时,执行以下操作:
- 取出队首节点,并将其标记为已访问。
- 遍历该节点的所有邻居节点,如果邻居节点未被访问过,则将其入队。
4. 重复步骤3,直至队列为空。
下面是基于邻接表存储有向图的广度优先遍历的C语言代码实现,假设邻接表存储在一个数组中,每个节点的邻居节点存储在一个链表中:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX_NUM 100
// 邻接表节点的结构体
typedef struct ArcNode {
int adjvex; // 邻接节点的编号
struct ArcNode *next; // 指向下一个邻接节点的指针
} ArcNode;
// 顶点节点的结构体
typedef struct {
int data; // 顶点的数据
ArcNode *firstarc; // 指向第一个邻接节点的指针
} VNode;
// 邻接表的结构体
typedef struct {
VNode vertices[MAX_VERTEX_NUM]; // 顶点数组
int vexnum; // 顶点数
int arcnum; // 边数
} ALGraph;
// 初始化邻接表
void InitGraph(ALGraph *G)
{
int i;
G->vexnum = 0;
G->arcnum = 0;
for (i = 0; i < MAX_VERTEX_NUM; i++) {
G->vertices[i].data = 0;
G->vertices[i].firstarc = NULL;
}
}
// 添加边
void AddArc(ALGraph *G, int v, int w)
{
ArcNode *p;
p = (ArcNode *)malloc(sizeof(ArcNode));
p->adjvex = w;
p->next = G->vertices[v].firstarc;
G->vertices[v].firstarc = p;
G->arcnum++;
}
// 广度优先遍历
void BFS(ALGraph *G, int v)
{
int visited[MAX_VERTEX_NUM] = {0}; // 标记数组,记录节点是否被访问过
int q[MAX_VERTEX_NUM]; // 队列
int front = 0, rear = 0; // 队头和队尾指针
int i, j;
ArcNode *p;
q[rear++] = v; // 将起点节点入队
visited[v] = 1; // 标记起点节点为已访问
while (front < rear) {
i = q[front++]; // 取出队首节点
printf("%d ", i); // 访问该节点
p = G->vertices[i].firstarc;
while (p != NULL) {
j = p->adjvex;
if (!visited[j]) { // 如果邻居节点未被访问过,则将其入队
q[rear++] = j;
visited[j] = 1;
}
p = p->next;
}
}
}
int main()
{
ALGraph G;
int n, m, i, v, w;
printf("请输入顶点数和边数:\n");
scanf("%d%d", &n, &m);
InitGraph(&G);
G.vexnum = n;
printf("请输入顶点的数据:\n");
for (i = 0; i < n; i++) {
scanf("%d", &G.vertices[i].data);
}
printf("请输入每条边的起点和终点:\n");
for (i = 0; i < m; i++) {
scanf("%d%d", &v, &w);
AddArc(&G, v, w);
}
printf("广度优先遍历结果为:\n");
BFS(&G, 0);
printf("\n");
return 0;
}
```
这段代码可以读入有向图的顶点数和边数,然后按照邻接表的方式存储图,并对起点节点进行广度优先遍历,输出访问的节点序列。
阅读全文