用C语言写一段代码,有向无权图的建立、删除、修改、查找,用邻接表存储,并能从键盘输入
时间: 2023-12-14 21:38:28 浏览: 71
以下是用C语言实现有向无权图的建立、删除、修改、查找的代码,使用邻接表存储,并且可以从键盘输入:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX_NUM 100
// 边表结构体
typedef struct ArcNode {
int adjvex; // 邻接点的下标
struct ArcNode *nextarc; // 指向下一条边的指针
} ArcNode;
// 顶点表结构体
typedef struct VNode {
char data; // 顶点信息
ArcNode *firstarc; // 指向第一条依附于该顶点的边的指针
} VNode, AdjList[MAX_VERTEX_NUM];
// 图结构体
typedef struct {
AdjList vertices; // 邻接表
int vexnum, arcnum; // 顶点数和边数
} ALGraph;
// 初始化有向图
void InitGraph(ALGraph *G) {
int i;
G->vexnum = G->arcnum = 0;
for (i = 0; i < MAX_VERTEX_NUM; i++) {
G->vertices[i].data = ' ';
G->vertices[i].firstarc = NULL;
}
}
// 添加顶点
void AddVertex(ALGraph *G) {
char data;
printf("请输入要添加的顶点信息:");
scanf(" %c", &data);
G->vertices[G->vexnum].data = data;
G->vexnum++;
}
// 添加边
void AddArc(ALGraph *G) {
int i, j;
printf("请输入要添加的边的起点和终点的下标(用空格隔开):");
scanf("%d %d", &i, &j);
ArcNode *p = (ArcNode *)malloc(sizeof(ArcNode));
p->adjvex = j;
p->nextarc = G->vertices[i].firstarc;
G->vertices[i].firstarc = p;
G->arcnum++;
}
// 删除顶点
void DeleteVertex(ALGraph *G) {
int i, j;
printf("请输入要删除的顶点下标:");
scanf("%d", &i);
// 删除该顶点的所有出边
ArcNode *p = G->vertices[i].firstarc;
while (p != NULL) {
j = p->adjvex;
// 删除该顶点到其它顶点的边
ArcNode *q = G->vertices[j].firstarc;
ArcNode *r = NULL;
while (q != NULL && q->adjvex != i) {
r = q;
q = q->nextarc;
}
if (q != NULL) {
if (r == NULL) {
G->vertices[j].firstarc = q->nextarc;
} else {
r->nextarc = q->nextarc;
}
free(q);
G->arcnum--;
}
p = p->nextarc;
}
// 删除该顶点的入边
for (j = 0; j < G->vexnum; j++) {
p = G->vertices[j].firstarc;
ArcNode *r = NULL;
while (p != NULL && p->adjvex != i) {
r = p;
p = p->nextarc;
}
if (p != NULL) {
if (r == NULL) {
G->vertices[j].firstarc = p->nextarc;
} else {
r->nextarc = p->nextarc;
}
free(p);
G->arcnum--;
}
}
// 删除该顶点
for (j = i; j < G->vexnum - 1; j++) {
G->vertices[j] = G->vertices[j+1];
}
G->vexnum--;
}
// 删除边
void DeleteArc(ALGraph *G) {
int i, j;
printf("请输入要删除的边的起点和终点的下标(用空格隔开):");
scanf("%d %d", &i, &j);
// 删除该边
ArcNode *p = G->vertices[i].firstarc;
ArcNode *r = NULL;
while (p != NULL && p->adjvex != j) {
r = p;
p = p->nextarc;
}
if (p != NULL) {
if (r == NULL) {
G->vertices[i].firstarc = p->nextarc;
} else {
r->nextarc = p->nextarc;
}
free(p);
G->arcnum--;
}
}
// 修改顶点信息
void ModifyVertex(ALGraph *G) {
int i;
char data;
printf("请输入要修改的顶点下标和新的顶点信息(用空格隔开):");
scanf("%d %c", &i, &data);
G->vertices[i].data = data;
}
// 查找顶点
void FindVertex(ALGraph *G) {
int i;
char data;
printf("请输入要查找的顶点信息:");
scanf(" %c", &data);
for (i = 0; i < G->vexnum; i++) {
if (G->vertices[i].data == data) {
printf("该顶点的下标为:%d\n", i);
return;
}
}
printf("未找到该顶点。\n");
}
// 输出邻接表
void PrintGraph(ALGraph G) {
int i;
ArcNode *p;
printf("有向图的邻接表为:\n");
for (i = 0; i < G.vexnum; i++) {
printf("%c -> ", G.vertices[i].data);
p = G.vertices[i].firstarc;
while (p != NULL) {
printf("%c -> ", G.vertices[p->adjvex].data);
p = p->nextarc;
}
printf("NULL\n");
}
}
int main() {
int choice;
ALGraph G;
InitGraph(&G);
while (1) {
printf("\n");
printf("1. 添加顶点\n");
printf("2. 添加边\n");
printf("3. 删除顶点\n");
printf("4. 删除边\n");
printf("5. 修改顶点信息\n");
printf("6. 查找顶点\n");
printf("7. 输出邻接表\n");
printf("8. 退出\n");
printf("请选择操作:");
scanf("%d", &choice);
switch (choice) {
case 1:
AddVertex(&G);
break;
case 2:
AddArc(&G);
break;
case 3:
DeleteVertex(&G);
break;
case 4:
DeleteArc(&G);
break;
case 5:
ModifyVertex(&G);
break;
case 6:
FindVertex(&G);
break;
case 7:
PrintGraph(G);
break;
case 8:
exit(0);
default:
printf("输入有误,请重新输入。\n");
}
}
return 0;
}
```
注意,这段代码中使用了邻接表来存储有向图,其中顶点表是一个数组,每个元素是一个结构体,包含顶点信息和指向第一条依附于该顶点的边的指针;边表是一个结构体,包含邻接点的下标和指向下一条边的指针。具体实现细节可以看代码注释。
阅读全文