用C语言写一段代码,有向无权图的建立、删除、修改、查询并用拓扑排序检验连通性,用邻接矩阵存储,可以从文件读取数据 并进行键盘操作
时间: 2024-01-24 11:17:15 浏览: 72
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX_NUM 100 // 定义图中最大顶点数
#define MAX_EDGE_NUM 10000 // 定义图中最大边数
// 定义邻接矩阵存储结构体
typedef struct {
int edges[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 存储各条边的信息
int vertex_num; // 存储顶点数
int edge_num; // 存储边数
} Graph;
// 创建图
void createGraph(Graph* graph) {
printf("请输入顶点数和边数:\n");
scanf("%d%d", &graph->vertex_num, &graph->edge_num);
// 初始化邻接矩阵
for (int i = 0; i < graph->vertex_num; i++) {
for (int j = 0; j < graph->vertex_num; j++) {
graph->edges[i][j] = 0;
}
}
// 添加边
printf("请输入每条边的起点和终点:\n");
for (int i = 0; i < graph->edge_num; i++) {
int start, end;
scanf("%d%d", &start, &end);
graph->edges[start][end] = 1;
}
}
// 删除边
void deleteEdge(Graph* graph) {
int start, end;
printf("请输入要删除的边的起点和终点:\n");
scanf("%d%d", &start, &end);
if (graph->edges[start][end] == 1) {
graph->edges[start][end] = 0;
printf("删除成功!\n");
} else {
printf("该边不存在!\n");
}
}
// 修改边
void modifyEdge(Graph* graph) {
int start, end;
printf("请输入要修改的边的起点和终点:\n");
scanf("%d%d", &start, &end);
if (graph->edges[start][end] == 1) {
graph->edges[start][end] = 0;
printf("请输入修改后的终点:\n");
scanf("%d", &end);
graph->edges[start][end] = 1;
printf("修改成功!\n");
} else {
printf("该边不存在!\n");
}
}
// 查询边
void queryEdge(Graph* graph) {
int start, end;
printf("请输入要查询的边的起点和终点:\n");
scanf("%d%d", &start, &end);
if (graph->edges[start][end] == 1) {
printf("该边存在!\n");
} else {
printf("该边不存在!\n");
}
}
// 拓扑排序
int topologicalSort(Graph* graph) {
int inDegree[MAX_VERTEX_NUM] = {0}; // 存储每个顶点的入度
int queue[MAX_VERTEX_NUM], front = 0, rear = -1; // 定义队列
int count = 0; // 存储已经输出的顶点数
// 计算每个顶点的入度
for (int i = 0; i < graph->vertex_num; i++) {
for (int j = 0; j < graph->vertex_num; j++) {
if (graph->edges[i][j] == 1) {
inDegree[j]++;
}
}
}
// 将入度为0的顶点入队
for (int i = 0; i < graph->vertex_num; i++) {
if (inDegree[i] == 0) {
queue[++rear] = i;
}
}
// 拓扑排序
while (front <= rear) {
int current_vertex = queue[front++]; // 出队一个顶点
printf("%d ", current_vertex); // 输出该顶点
// 将该顶点能够到达的顶点的入度减1
for (int i = 0; i < graph->vertex_num; i++) {
if (graph->edges[current_vertex][i] == 1) {
inDegree[i]--;
if (inDegree[i] == 0) { // 如果该顶点的入度为0,将其入队
queue[++rear] = i;
}
}
}
count++;
}
if (count == graph->vertex_num) { // 如果已经输出了所有顶点,说明图是连通的
printf("\n图是连通的!\n");
return 1;
} else {
printf("\n图不是连通的!\n");
return -1;
}
}
// 键盘操作
void keyboardOperation(Graph* graph) {
int choice;
while (1) {
printf("\n请选择您要执行的操作:\n");
printf("1. 创建图\n");
printf("2. 删除边\n");
printf("3. 修改边\n");
printf("4. 查询边\n");
printf("5. 拓扑排序并检验连通性\n");
printf("6. 退出程序\n");
scanf("%d", &choice);
switch (choice) {
case 1:
createGraph(graph);
break;
case 2:
deleteEdge(graph);
break;
case 3:
modifyEdge(graph);
break;
case 4:
queryEdge(graph);
break;
case 5:
topologicalSort(graph);
break;
case 6:
exit(0);
default:
printf("输入有误,请重新输入!\n");
}
}
}
int main() {
Graph graph;
keyboardOperation(&graph);
return 0;
}
```
阅读全文