给定一个图,用c语言设计一个程序,从键盘输入数据建立图的邻接表存储,从该图的某一顶点开始进行深度优先遍历和广度优先遍历。
时间: 2024-02-18 12:05:27 浏览: 118
好的,让我为你解答这个问题。
首先,我们需要定义一些数据结构来表示图的顶点和边。邻接表是一种常用的存储图的方式,它用链表来表示每个顶点的邻居。
下面是一个简单的 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 语言实现图的深度优先遍历和广度优先遍历的方法。希望对你有所帮助!
阅读全文