用c语言创建一个无向图,选用邻接表法数据存储结构,并求出任意一个顶的度。同时写出图的深度,广度遍历算法,以及注释出每一个步骤的作用
时间: 2023-12-04 18:05:23 浏览: 82
dg.zip_dirtddf_图 数据结构_数据结构 图_数据结构 C语言_有向图
好的,我来为您解答。首先,我们需要了解一下邻接表法这种数据存储结构。
邻接表法是一种图的存储方式,它将每个顶点的所有邻接点存储在一个链表中。具体实现时,我们可以用一个数组来存储所有顶点,每个数组元素对应一个链表,存储该顶点的所有邻接点。
下面是用C语言实现无向图的代码,采用邻接表法:
```c
#include <stdio.h>
#include <stdlib.h>
// 定义邻接表的边节点结构体
struct EdgeNode {
int adjvex; // 邻接点的索引
struct EdgeNode *next; // 指向下一个邻接点的指针
};
// 定义邻接表的顶点结构体
struct VertexNode {
int data; // 顶点的数据
struct EdgeNode *firstedge; // 指向第一个邻接点的指针
};
// 定义无向图结构体
struct Graph {
int vertexNum; // 图的顶点数
int edgeNum; // 图的边数
struct VertexNode *vertexList; // 顶点数组
};
// 创建邻接表无向图
void createGraph(struct Graph *graph) {
printf("请输入图的顶点数和边数:\n");
scanf("%d %d", &graph->vertexNum, &graph->edgeNum);
graph->vertexList = (struct VertexNode*)malloc(sizeof(struct VertexNode) * graph->vertexNum);
// 初始化每个顶点的邻接链表为空
for (int i = 0; i < graph->vertexNum; i++) {
graph->vertexList[i].data = i;
graph->vertexList[i].firstedge = NULL;
}
printf("请输入每条边的起点和终点:\n");
// 添加边节点
for (int i = 0; i < graph->edgeNum; i++) {
int source, dest;
scanf("%d %d", &source, &dest);
// 添加 source -> dest 的边
struct EdgeNode *edge = (struct EdgeNode*)malloc(sizeof(struct EdgeNode));
edge->adjvex = dest;
edge->next = graph->vertexList[source].firstedge;
graph->vertexList[source].firstedge = edge;
// 添加 dest -> source 的边
edge = (struct EdgeNode*)malloc(sizeof(struct EdgeNode));
edge->adjvex = source;
edge->next = graph->vertexList[dest].firstedge;
graph->vertexList[dest].firstedge = edge;
}
}
// 计算某个顶点的度
int degree(struct Graph *graph, int vertex) {
int degree = 0;
struct EdgeNode *edge = graph->vertexList[vertex].firstedge;
while (edge != NULL) {
degree++;
edge = edge->next;
}
return degree;
}
// 深度优先遍历
void dfs(struct Graph *graph, int vertex, int *visited) {
printf("%d ", vertex);
visited[vertex] = 1;
struct EdgeNode *edge = graph->vertexList[vertex].firstedge;
while (edge != NULL) {
if (!visited[edge->adjvex]) {
dfs(graph, edge->adjvex, visited);
}
edge = edge->next;
}
}
// 广度优先遍历
void bfs(struct Graph *graph, int vertex, int *visited) {
int queue[1000];
int front = 0, rear = 0;
printf("%d ", vertex);
visited[vertex] = 1;
queue[rear++] = vertex;
while (front < rear) {
int cur = queue[front++];
struct EdgeNode *edge = graph->vertexList[cur].firstedge;
while (edge != NULL) {
if (!visited[edge->adjvex]) {
printf("%d ", edge->adjvex);
visited[edge->adjvex] = 1;
queue[rear++] = edge->adjvex;
}
edge = edge->next;
}
}
}
int main() {
struct Graph graph;
createGraph(&graph);
printf("请输入要查询度的顶点:\n");
int vertex;
scanf("%d", &vertex);
printf("%d 的度为 %d\n", vertex, degree(&graph, vertex));
printf("深度优先遍历结果为:\n");
int visited[graph.vertexNum];
for (int i = 0; i < graph.vertexNum; i++) {
visited[i] = 0;
}
dfs(&graph, 0, visited);
printf("\n");
printf("广度优先遍历结果为:\n");
for (int i = 0; i < graph.vertexNum; i++) {
visited[i] = 0;
}
bfs(&graph, 0, visited);
printf("\n");
return 0;
}
```
在这段代码中,我们用 `struct Graph` 结构体表示无向图,其中包含了图的顶点数、边数和顶点数组,每个顶点又由 `struct VertexNode` 结构体表示,其中包含了该顶点的数据和指向第一个邻接点的指针。邻接点通过 `struct EdgeNode` 结构体表示,其中包含了邻接点的索引和指向下一个邻接点的指针。
`createGraph` 函数用于创建邻接表无向图,它首先读入图的顶点数和边数,然后动态分配顶点数组的内存,并将每个顶点的邻接链表初始化为空。接着,它读入每条边的起点和终点,然后分别添加 source -> dest 和 dest -> source 两条边的边节点到对应的邻接链表中。
`degree` 函数用于计算某个顶点的度,它遍历该顶点的邻接链表,统计邻接点的个数即可。
`dfs` 函数为深度优先遍历算法,它从指定的顶点开始遍历,先输出该顶点,然后递归遍历其所有未被访问过的邻接点,直到所有顶点都被访问过为止。
`bfs` 函数为广度优先遍历算法,它从指定的顶点开始遍历,先输出该顶点,然后将该顶点加入队列中,并标记为已访问。然后不断从队列中取出一个顶点,遍历其所有未被访问过的邻接点,将它们加入队列中,并标记为已访问,直到队列为空为止。
最后,我们在 `main` 函数中调用上述函数,得到某个顶点的度,以及图的深度、广度遍历结果。
阅读全文