给定一个图,用c语言设计一个程序,从键盘输入数据建立图的邻接表存储,从该图的某一顶点开始进行深度优先遍历和广度优先遍历。
时间: 2024-02-18 19:05:27 浏览: 112
建立图的邻接矩阵或邻接表存储并在此基础上实现图的深度优先遍历和广度优先遍历.doc
5星 · 资源好评率100%
好的,让我为你解答这个问题。
首先,我们需要定义一些数据结构来表示图的顶点和边。邻接表是一种常用的存储图的方式,它用链表来表示每个顶点的邻居。
下面是一个简单的 C 代码来定义这些数据结构:
```c
#include <stdio.h>
#include <stdlib.h>
// 邻接表中的边
typedef struct edge {
int dest; // 目标顶点
struct edge* next; // 指向下一条边的指针
} edge_t;
// 邻接表中的顶点
typedef struct vertex {
int id; // 顶点的编号
edge_t* edges; // 指向第一条边的指针
} vertex_t;
// 图
typedef struct graph {
int num_vertices; // 顶点的数量
vertex_t* vertices; // 指向第一个顶点的指针
} graph_t;
```
接下来,我们需要编写函数来读取图的邻接表存储。下面的代码从标准输入中读取两个整数 n 和 m,表示顶点的数量和边的数量,然后读取 m 行,每行包含两个整数 u 和 v,表示一条从顶点 u 到顶点 v 的边。
```c
// 从标准输入中读取图的邻接表存储
graph_t* read_graph() {
int n, m;
scanf("%d %d", &n, &m);
// 创建一个新的图
graph_t* graph = (graph_t*) malloc(sizeof(graph_t));
graph->num_vertices = n;
graph->vertices = (vertex_t*) malloc(n * sizeof(vertex_t));
// 初始化每个顶点
for (int i = 0; i < n; i++) {
graph->vertices[i].id = i;
graph->vertices[i].edges = NULL;
}
// 读取每条边,并将其添加到邻接表中
for (int i = 0; i < m; i++) {
int u, v;
scanf("%d %d", &u, &v);
edge_t* edge1 = (edge_t*) malloc(sizeof(edge_t));
edge1->dest = v;
edge1->next = graph->vertices[u].edges;
graph->vertices[u].edges = edge1;
edge_t* edge2 = (edge_t*) malloc(sizeof(edge_t));
edge2->dest = u;
edge2->next = graph->vertices[v].edges;
graph->vertices[v].edges = edge2;
}
return graph;
}
```
现在我们可以开始实现深度优先遍历和广度优先遍历算法了。为了避免重复访问顶点,我们需要使用一个数组来记录每个顶点是否已经被访问过。
下面是深度优先遍历算法的代码。它从指定的顶点开始遍历,并打印出遍历的顺序。
```c
// 深度优先遍历
void dfs(graph_t* graph, int start, int* visited) {
visited[start] = 1;
printf("%d ", start);
edge_t* edge = graph->vertices[start].edges;
while (edge != NULL) {
int dest = edge->dest;
if (!visited[dest]) {
dfs(graph, dest, visited);
}
edge = edge->next;
}
}
```
下面是广度优先遍历算法的代码。它从指定的顶点开始遍历,并打印出遍历的顺序。
```c
// 广度优先遍历
void bfs(graph_t* graph, int start, int* visited) {
int queue[graph->num_vertices];
int front = 0, rear = 0;
visited[start] = 1;
printf("%d ", start);
queue[rear++] = start;
while (front < rear) {
int current = queue[front++];
edge_t* edge = graph->vertices[current].edges;
while (edge != NULL) {
int dest = edge->dest;
if (!visited[dest]) {
visited[dest] = 1;
printf("%d ", dest);
queue[rear++] = dest;
}
edge = edge->next;
}
}
}
```
最后,我们可以在主函数中调用这些函数来测试我们的程序。
```c
int main() {
graph_t* graph = read_graph();
int* visited = (int*) calloc(graph->num_vertices, sizeof(int));
printf("DFS: ");
dfs(graph, 0, visited);
printf("\n");
memset(visited, 0, graph->num_vertices * sizeof(int));
printf("BFS: ");
bfs(graph, 0, visited);
printf("\n");
return 0;
}
```
这就是用 C 语言实现图的深度优先遍历和广度优先遍历的方法。希望对你有所帮助!
阅读全文