用C语言试编写一个程序,完成在连通 无向图上访问图中全部顶点及相关基本操作。 【基本要求】 以图的邻接表为存储结构,实现连通无向图的深度优先和广度优先遍历。以用户指定的 顶点为起点,分别输出每种遍历下的结点访问序列及图的各相应生成树的边集。 【测试数据】 自行设计一个至少含10个顶点、14条边的无向连通图。 【实现提示】 设图的顶点不超过 30个,每个顶点用一个编号表示(如果一个图有n个顶点,则它们的编号分别为1,2,,n)。通过输入图的全部边的信息建立一个图,每条边为一个数对,可以对边的顺序做出某种限制。注意,生成树的边是有向的,顶点顺序不能颠倒。
时间: 2024-03-15 10:46:57 浏览: 66
好的,这是一个比较复杂的问题,需要分几步来完成。首先,我们需要定义一个图的邻接表结构体,用来存储图的信息:
```c
#define MAX_VERTEX_NUM 30 // 顶点最大个数
typedef struct ArcNode { // 边结点
int adjvex; // 相邻的顶点编号
struct ArcNode *next; // 指向下一条边的指针
} ArcNode;
typedef struct VNode { // 顶点结点
int data; // 顶点编号
ArcNode *firstarc; // 指向第一条边的指针
} VNode, AdjList[MAX_VERTEX_NUM];
typedef struct { // 图结构体
AdjList vertices; // 顶点表
int vexnum, arcnum; // 顶点数和边数
} Graph;
```
然后,我们需要实现一个函数来创建图:
```c
void createGraph(Graph *G) {
int i, j, k;
ArcNode *e;
printf("请输入顶点数和边数:");
scanf("%d%d", &G->vexnum, &G->arcnum);
for (i = 0; i < G->vexnum; i++) { // 初始化顶点表
G->vertices[i].data = i+1;
G->vertices[i].firstarc = NULL;
}
printf("请输入边的信息(起点、终点):\n");
for (k = 0; k < G->arcnum; k++) { // 建立邻接表
scanf("%d%d", &i, &j);
e = (ArcNode *)malloc(sizeof(ArcNode));
e->adjvex = j-1;
e->next = G->vertices[i-1].firstarc;
G->vertices[i-1].firstarc = e;
e = (ArcNode *)malloc(sizeof(ArcNode));
e->adjvex = i-1;
e->next = G->vertices[j-1].firstarc;
G->vertices[j-1].firstarc = e;
}
}
```
接下来,我们需要实现深度优先遍历和广度优先遍历两个函数,以及用于遍历的辅助函数`DFS`和`BFS`:
```c
void DFS(Graph G, int v, int visited[]) { // 深度优先遍历
ArcNode *p;
visited[v] = 1;
printf("%d ", G.vertices[v].data);
for (p = G.vertices[v].firstarc; p; p = p->next) {
if (!visited[p->adjvex]) {
DFS(G, p->adjvex, visited);
}
}
}
void BFS(Graph G, int v, int visited[]) { // 广度优先遍历
int queue[MAX_VERTEX_NUM], front = 0, rear = 0;
ArcNode *p;
visited[v] = 1;
printf("%d ", G.vertices[v].data);
queue[rear++] = v;
while (front < rear) {
v = queue[front++];
for (p = G.vertices[v].firstarc; p; p = p->next) {
if (!visited[p->adjvex]) {
visited[p->adjvex] = 1;
printf("%d ", G.vertices[p->adjvex].data);
queue[rear++] = p->adjvex;
}
}
}
}
void DFSTraverse(Graph G) { // 深度优先遍历整个图
int i, visited[MAX_VERTEX_NUM] = {0}; // visited数组用于记录每个顶点是否被访问过
printf("深度优先遍历:");
for (i = 0; i < G.vexnum; i++) { // 遍历所有顶点
if (!visited[i]) {
DFS(G, i, visited);
}
}
printf("\n");
}
void BFSTraverse(Graph G) { // 广度优先遍历整个图
int i, visited[MAX_VERTEX_NUM] = {0};
printf("广度优先遍历:");
for (i = 0; i < G.vexnum; i++) {
if (!visited[i]) {
BFS(G, i, visited);
}
}
printf("\n");
}
```
最后,我们可以实现一个主函数来测试我们的代码:
```c
int main() {
Graph G;
createGraph(&G);
DFSTraverse(G);
BFSTraverse(G);
return 0;
}
```
这个程序可以读入一个无向图的顶点数和边数,然后读入每条边的信息,最后输出深度优先遍历和广度优先遍历的结果。需要注意的是,这里我们没有考虑生成树的问题,如果需要输出生成树的边集,可以在遍历时记录访问的边,然后输出即可。
阅读全文