写一个C语言程序,内容为使用图的邻接矩阵的存储结构实现有向图、无向图和网的建立算法,并实现深度优先遍历及广度优先遍历
时间: 2024-02-17 08:02:37 浏览: 79
好的,以下是实现有向图、无向图和网的建立算法,并实现深度优先遍历及广度优先遍历的 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;
}
```
程序运行时,首先会要求输入图类型、顶点数和边数等信息,然后依次输入各个顶点的信息和边的信息。最后输出图的邻接矩阵表示、深度优先遍历结果和广度优先遍历结果。
注意:本程序中使用了动态分配数组的方式存储访问状态,避免了在编译时确定数组大小的问题。同时,由于邻接矩阵的存储结构会占用较多的空间,因此在实际应用中可能并不常用。
阅读全文