首先先依次输入有向图的顶点信息,再依次输入有向图的弧信息,建立图的邻接表存储结构并将其打印输出; 接着在之前建立的有向图的邻接表存储结构基础上使用非递归算法对图进行深度优先搜索遍历并输出顶点序列; 最后在1中建立的有向图的邻接表存储结构基础上对图进行广度优先搜索遍历并输出顶点序列。用C语言实现
时间: 2024-02-11 17:06:49 浏览: 78
编写算法,由依次输入的顶点数目、狐的数目、各顶点的信息和各条狐的信息建立有向图的邻接表
好的,以下是使用C语言实现的代码:
```
#include <stdio.h>
#include <stdlib.h>
// 邻接表中的边结构体
typedef struct EdgeNode {
int adjvex; // 邻接顶点的下标
struct EdgeNode *next; // 指向下一条边的指针
} EdgeNode;
// 邻接表中的顶点结构体
typedef struct VertexNode {
char data; // 顶点信息
EdgeNode *firstedge; // 指向第一条依附该顶点的边的指针
} VertexNode, AdjList[100];
// 邻接表结构体
typedef struct {
AdjList adjList;
int numVertexes, numEdges; // 顶点数和边数
} GraphAdjList;
// 初始化邻接表
void InitGraph(GraphAdjList *G) {
int i, j, k;
EdgeNode *e;
printf("请输入顶点数和边数:\n");
scanf("%d%d", &G->numVertexes, &G->numEdges);
printf("请输入顶点信息:\n");
for (i = 0; i < G->numVertexes; i++) {
scanf(" %c", &G->adjList[i].data);
G->adjList[i].firstedge = NULL; // 初始化指针为空
}
printf("请输入边的信息:\n");
for (k = 0; k < G->numEdges; k++) {
printf("请输入边(vi, vj)中的顶点序号:\n");
scanf("%d%d", &i, &j);
e = (EdgeNode *)malloc(sizeof(EdgeNode)); // 生成新边结点
e->adjvex = j; // 邻接点序号为j
e->next = G->adjList[i].firstedge; // 将e指针指向当前顶点指向的结构体
G->adjList[i].firstedge = e; // 将当前顶点的指针指向e
}
}
// 深度优先遍历
void DFS(GraphAdjList G, int i, int *visited) {
EdgeNode *p;
visited[i] = 1; // 标记该节点已被访问
printf("%c ", G.adjList[i].data); // 打印节点信息
p = G.adjList[i].firstedge; // 指向当前节点的第一条边
while (p) {
if (!visited[p->adjvex]) { // 如果该节点未被访问
DFS(G, p->adjvex, visited); // 递归访问该节点
}
p = p->next; // 继续访问当前节点的下一条边
}
}
// 非递归深度优先遍历
void DFS_NonRecursive(GraphAdjList G) {
int visited[100] = {0}; // 初始化所有节点未被访问
EdgeNode *stack[100]; // 用数组模拟栈
int top = -1, i;
for (i = 0; i < G.numVertexes; i++) {
if (!visited[i]) { // 如果该节点未被访问
visited[i] = 1; // 标记该节点已被访问
printf("%c ", G.adjList[i].data); // 打印节点信息
stack[++top] = G.adjList[i].firstedge; // 将第一条边入栈
while (top != -1) {
EdgeNode *p = stack[top--]; // 取出栈顶元素
while (p) {
if (!visited[p->adjvex]) { // 如果该节点未被访问
visited[p->adjvex] = 1; // 标记该节点已被访问
printf("%c ", G.adjList[p->adjvex].data); // 打印节点信息
stack[++top] = p->next; // 将下一条边入栈
p = G.adjList[p->adjvex].firstedge; // 继续访问该节点的第一条边
} else {
p = p->next; // 继续访问该节点的下一条边
}
}
}
}
}
}
// 广度优先遍历
void BFS(GraphAdjList G) {
int visited[100] = {0}; // 初始化所有节点未被访问
EdgeNode *queue[100]; // 用数组模拟队列
int front = 0, rear = 0, i;
EdgeNode *p;
for (i = 0; i < G.numVertexes; i++) {
if (!visited[i]) { // 如果该节点未被访问
visited[i] = 1; // 标记该节点已被访问
printf("%c ", G.adjList[i].data); // 打印节点信息
queue[rear++] = G.adjList[i].firstedge; // 将第一条边入队
while (front != rear) {
p = queue[front++]; // 取出队头元素
while (p) {
if (!visited[p->adjvex]) { // 如果该节点未被访问
visited[p->adjvex] = 1; // 标记该节点已被访问
printf("%c ", G.adjList[p->adjvex].data); // 打印节点信息
queue[rear++] = G.adjList[p->adjvex].firstedge; // 将下一条边入队
}
p = p->next; // 继续访问该节点的下一条边
}
}
}
}
}
int main() {
GraphAdjList G;
InitGraph(&G);
printf("图的邻接表存储结构如下:\n");
int i;
for (i = 0; i < G.numVertexes; i++) {
printf("%c -> ", G.adjList[i].data);
EdgeNode *p = G.adjList[i].firstedge;
while (p) {
printf("%c -> ", G.adjList[p->adjvex].data);
p = p->next;
}
printf("NULL\n");
}
printf("使用非递归算法对图进行深度优先搜索遍历,顶点序列为:\n");
DFS_NonRecursive(G);
printf("\n使用递归算法对图进行深度优先搜索遍历,顶点序列为:\n");
int visited[100] = {0};
for (i = 0; i < G.numVertexes; i++) {
if (!visited[i]) {
DFS(G, i, visited);
}
}
printf("\n使用广度优先搜索遍历,顶点序列为:\n");
BFS(G);
printf("\n");
return 0;
}
```
注意:代码中顶点数和边数的上限为100,如果需要更多的节点和边,请根据实际情况修改代码。另外,程序中输入的顶点下标从0开始,如果需要从1开始,请在输入和输出节点信息时将下标加1即可。
阅读全文