图的两种遍历方法及对应的生成树。把图的深度优先遍历、广度优先遍历改为输出深度优先生成树、广度优先生成树。请帮我用c语言代码实现
时间: 2024-03-24 14:39:45 浏览: 59
下面是使用 C 语言实现深度优先遍历和生成树的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX_NUM 100 // 图中最多顶点数
typedef struct EdgeNode { // 边表结点
int adjvex; // 邻接点位置
struct EdgeNode *next; // 指向下一个邻接点的指针
} EdgeNode;
typedef struct VertexNode { // 顶点表结点
int data; // 顶点数据
EdgeNode *firstedge; // 指向第一个邻接点的指针
} VertexNode, AdjList[MAX_VERTEX_NUM];
typedef struct Graph { // 邻接表结构体
AdjList adjList; // 邻接表
int vexnum, arcnum; // 顶点数和边数
} Graph;
typedef struct stack { // 栈结构体
int data[MAX_VERTEX_NUM];
int top;
} Stack;
void InitStack(Stack *S) { // 初始化栈
S->top = -1;
}
int IsEmpty(Stack *S) { // 判断栈是否为空
return S->top == -1;
}
int Push(Stack *S, int x) { // 入栈
if (S->top == MAX_VERTEX_NUM - 1) { // 栈满
return 0;
}
S->top++;
S->data[S->top] = x;
return 1;
}
int Pop(Stack *S) { // 出栈
if (IsEmpty(S)) { // 栈空
return 0;
}
S->top--;
return 1;
}
int GetTop(Stack *S) { // 获取栈顶元素
if (IsEmpty(S)) { // 栈空
return -1;
}
return S->data[S->top];
}
void CreateGraph(Graph *G) { // 创建邻接表
printf("请输入顶点数和边数:");
scanf("%d%d", &(G->vexnum), &(G->arcnum));
for (int i = 0; i < G->vexnum; i++) { // 初始化顶点表
printf("请输入第%d个顶点的数据:", i + 1);
scanf("%d", &(G->adjList[i].data));
G->adjList[i].firstedge = NULL;
}
for (int i = 0; i < G->arcnum; i++) { // 构造边表
int u, v;
printf("请输入第%d条边的起点和终点:", i + 1);
scanf("%d%d", &u, &v);
EdgeNode *e = (EdgeNode *)malloc(sizeof(EdgeNode));
e->adjvex = v - 1;
e->next = G->adjList[u - 1].firstedge;
G->adjList[u - 1].firstedge = e;
}
}
void DFS(Graph *G, int v, int visited[], Stack *S) { // 深度优先遍历
visited[v] = 1; // 标记该顶点已被访问
printf("%d ", G->adjList[v].data); // 输出顶点数据
EdgeNode *e = G->adjList[v].firstedge;
while (e) { // 访问该顶点的所有邻接点
if (!visited[e->adjvex]) { // 如果邻接点未被访问
DFS(G, e->adjvex, visited, S); // 递归访问邻接点
Push(S, e->adjvex); // 将该邻接点入栈
}
e = e->next;
}
}
void DFSTree(Graph *G, int v, int visited[], Stack *S) { // 深度优先生成树
visited[v] = 1; // 标记该顶点已被访问
EdgeNode *e = G->adjList[v].firstedge;
while (e) { // 访问该顶点的所有邻接点
if (!visited[e->adjvex]) { // 如果邻接点未被访问
printf("%d -> %d\n", G->adjList[v].data, G->adjList[e->adjvex].data); // 输出生成树的一条边
DFSTree(G, e->adjvex, visited, S); // 递归访问邻接点
}
e = e->next;
}
}
void BFS(Graph *G, int v, int visited[], int queue[], int front, int rear) { // 广度优先遍历
visited[v] = 1; // 标记该顶点已被访问
printf("%d ", G->adjList[v].data); // 输出顶点数据
queue[rear] = v; // 将该顶点入队
while (front <= rear) { // 队列非空
int u = queue[front]; // 取出队首元素
front++;
EdgeNode *e = G->adjList[u].firstedge;
while (e) { // 访问该顶点的所有邻接点
if (!visited[e->adjvex]) { // 如果邻接点未被访问
visited[e->adjvex] = 1; // 标记该邻接点已被访问
printf("%d ", G->adjList[e->adjvex].data); // 输出邻接点数据
printf("%d -> %d\n", G->adjList[u].data, G->adjList[e->adjvex].data); // 输出生成树的一条边
queue[++rear] = e->adjvex; // 将该邻接点入队
}
e = e->next;
}
}
}
void BFSTree(Graph *G, int v, int visited[], int queue[], int front, int rear) { // 广度优先生成树
visited[v] = 1; // 标记该顶点已被访问
queue[rear] = v; // 将该顶点入队
while (front <= rear) { // 队列非空
int u = queue[front]; // 取出队首元素
front++;
EdgeNode *e = G->adjList[u].firstedge;
while (e) { // 访问该顶点的所有邻接点
if (!visited[e->adjvex]) { // 如果邻接点未被访问
visited[e->adjvex] = 1; // 标记该邻接点已被访问
printf("%d -> %d\n", G->adjList[u].data, G->adjList[e->adjvex].data); // 输出生成树的一条边
queue[++rear] = e->adjvex; // 将该邻接点入队
}
e = e->next;
}
}
}
int main() {
Graph G;
CreateGraph(&G);
int visited[MAX_VERTEX_NUM] = {0}; // 初始化所有顶点未被访问
Stack S;
InitStack(&S);
printf("深度优先遍历:");
for (int i = 0; i < G.vexnum; i++) { // 从每个未被访问的顶点开始深度优先遍历
if (!visited[i]) {
DFS(&G, i, visited, &S);
Push(&S, i);
}
}
printf("\n深度优先生成树:\n");
int u = GetTop(&S);
while (!IsEmpty(&S)) { // 从栈顶开始深度优先生成树
int v = GetTop(&S);
Pop(&S);
if (!visited[v]) {
DFSTree(&G, v, visited, &S);
}
u = v;
}
int visited2[MAX_VERTEX_NUM] = {0}; // 初始化所有顶点未被访问
int queue[MAX_VERTEX_NUM], front = 0, rear = -1; // 初始化队列
printf("广度优先遍历:");
for (int i = 0; i < G.vexnum; i++) { // 从每个未被访问的顶点开始广度优先遍历
if (!visited2[i]) {
BFS(&G, i, visited2, queue, front, rear);
}
}
printf("\n广度优先生成树:\n");
front = 0;
rear = -1;
int visited3[MAX_VERTEX_NUM] = {0}; // 初始化所有顶点未被访问
for (int i = 0; i < G.vexnum; i++) { // 从每个未被访问的顶点开始广度优先生成树
if (!visited3[i]) {
BFSTree(&G, i, visited3, queue, front, rear);
}
}
return 0;
}
```
其中,深度优先生成树使用了栈,广度优先生成树使用了队列。
阅读全文