写一个C语言程序,内容为使用图的邻接矩阵的存储结构实现有向图、无向图和网的建立算法,并实现深度优先遍历及广度优先遍历
时间: 2024-02-17 10:02:37 浏览: 77
建立图的邻接矩阵或邻接表存储并在此基础上实现图的深度优先遍历和广度优先遍历.doc
5星 · 资源好评率100%
好的,以下是实现有向图、无向图和网的建立算法,并实现深度优先遍历及广度优先遍历的 C 语言程序。其中,图的邻接矩阵的存储结构使用二维数组表示。
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <limits.h>
#define MAX_VERTEX_NUM 100 // 最大顶点数
// 图的类型
typedef enum {
DG, // 有向图
DN, // 有向网
UG, // 无向图
UN // 无向网
} GraphType;
// 图的邻接矩阵存储结构
typedef struct {
int vertex[MAX_VERTEX_NUM]; // 存储顶点信息
int arc[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 存储边信息
int vertex_num; // 顶点数
int arc_num; // 边数
GraphType type; // 图类型
} MatrixGraph;
// 创建邻接矩阵表示的图
void create_graph(MatrixGraph *graph)
{
int i, j, k, w;
// 输入顶点数和边数
printf("请输入顶点数和边数:");
scanf("%d%d", &graph->vertex_num, &graph->arc_num);
// 输入顶点信息
printf("请依次输入各个顶点的信息:");
for (i = 0; i < graph->vertex_num; i++) {
scanf("%d", &graph->vertex[i]);
}
// 初始化邻接矩阵
for (i = 0; i < graph->vertex_num; i++) {
for (j = 0; j < graph->vertex_num; j++) {
graph->arc[i][j] = INT_MAX; // 初始化为极大值
}
}
// 输入边信息
printf("请依次输入各个边的信息(起点、终点、权值,以空格分隔):\n");
for (k = 0; k < graph->arc_num; k++) {
scanf("%d%d%d", &i, &j, &w);
graph->arc[i][j] = w; // 存储边信息
if (graph->type == UG || graph->type == UN) {
graph->arc[j][i] = w; // 无向图或网,存储对称边信息
}
}
}
// 输出邻接矩阵表示的图
void print_graph(MatrixGraph graph)
{
int i, j;
printf("顶点数:%d,边数:%d,图类型:", graph.vertex_num, graph.arc_num);
switch (graph.type) {
case DG:
printf("有向图\n");
break;
case DN:
printf("有向网\n");
break;
case UG:
printf("无向图\n");
break;
case UN:
printf("无向网\n");
break;
}
// 输出顶点信息
printf("顶点信息:");
for (i = 0; i < graph.vertex_num; i++) {
printf("%d ", graph.vertex[i]);
}
printf("\n");
// 输出边信息
printf("边信息:\n");
for (i = 0; i < graph.vertex_num; i++) {
for (j = 0; j < graph.vertex_num; j++) {
if (graph.arc[i][j] != INT_MAX) { // 存在边
printf("(%d,%d,%d) ", i, j, graph.arc[i][j]);
}
}
printf("\n");
}
}
// 深度优先遍历
void dfs(MatrixGraph graph, int v, bool *visited)
{
int i;
visited[v] = true; // 标记已访问
printf("%d ", graph.vertex[v]); // 输出顶点信息
for (i = 0; i < graph.vertex_num; i++) {
if (graph.arc[v][i] != INT_MAX && !visited[i]) { // 存在边且未访问
dfs(graph, i, visited); // 递归访问
}
}
}
// 深度优先遍历入口
void dfs_traversal(MatrixGraph graph)
{
int i;
bool *visited = (bool *) malloc(graph.vertex_num * sizeof(bool)); // 动态分配数组,存储访问状态
printf("深度优先遍历结果:");
for (i = 0; i < graph.vertex_num; i++) {
visited[i] = false; // 初始化为未访问
}
for (i = 0; i < graph.vertex_num; i++) {
if (!visited[i]) { // 未访问
dfs(graph, i, visited); // 从该顶点开始深度优先遍历
}
}
free(visited); // 释放数组空间
printf("\n");
}
// 广度优先遍历
void bfs(MatrixGraph graph, int v, bool *visited)
{
int queue[MAX_VERTEX_NUM]; // 定义队列
int front = 0, rear = 0; // 队列的头和尾
int i, u;
visited[v] = true; // 标记已访问
printf("%d ", graph.vertex[v]); // 输出顶点信息
queue[rear++] = v; // 入队
while (front != rear) { // 队列不为空
u = queue[front++]; // 出队
for (i = 0; i < graph.vertex_num; i++) {
if (graph.arc[u][i] != INT_MAX && !visited[i]) { // 存在边且未访问
visited[i] = true; // 标记已访问
printf("%d ", graph.vertex[i]); // 输出顶点信息
queue[rear++] = i; // 入队
}
}
}
}
// 广度优先遍历入口
void bfs_traversal(MatrixGraph graph)
{
int i;
bool *visited = (bool *) malloc(graph.vertex_num * sizeof(bool)); // 动态分配数组,存储访问状态
printf("广度优先遍历结果:");
for (i = 0; i < graph.vertex_num; i++) {
visited[i] = false; // 初始化为未访问
}
for (i = 0; i < graph.vertex_num; i++) {
if (!visited[i]) { // 未访问
bfs(graph, i, visited); // 从该顶点开始广度优先遍历
}
}
free(visited); // 释放数组空间
printf("\n");
}
int main()
{
MatrixGraph graph;
printf("请选择图类型(1:有向图,2:有向网,3:无向图,4:无向网):");
scanf("%d", &graph.type);
create_graph(&graph);
print_graph(graph);
dfs_traversal(graph);
bfs_traversal(graph);
return 0;
}
```
程序运行时,首先会要求输入图类型、顶点数和边数等信息,然后依次输入各个顶点的信息和边的信息。最后输出图的邻接矩阵表示、深度优先遍历结果和广度优先遍历结果。
注意:本程序中使用了动态分配数组的方式存储访问状态,避免了在编译时确定数组大小的问题。同时,由于邻接矩阵的存储结构会占用较多的空间,因此在实际应用中可能并不常用。
阅读全文