请用C语言设计并验证如下算法:带权图采用邻接表表示,实现无向图的广度优先搜索与有向图的深度优先搜索。要求如下:1. 本演示程序中,首先,从键盘输入图的节点数和边数以及图的类型(有向或无向),然后输入节点信息和边信息,然后依次执行无向图的深度优先搜索与有向图的广度优先搜索算法,根据要求输出搜索结果。 2. 演示程序以用户和计算机对话的方式进行,即在计算机终端上显示“提示信息”之后,由用户在键盘上输入节点数、边数、图的类型、节点信息和和边信息。输出遍历结果
时间: 2024-02-26 19:52:35 浏览: 64
好的,下面是基于邻接表的图搜索算法的C语言实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_VERTEX_NUM 100 // 最大节点数
// 邻接表中的边结构体
typedef struct edgeNode {
int adjvex; // 邻接点在顶点数组中的位置
int weight; // 边权值
struct edgeNode *next; // 链域指针
} EdgeNode;
// 邻接表中的顶点结构体
typedef struct vertexNode {
int data; // 节点信息
EdgeNode *firstEdge; // 指向第一个邻接点的指针
} VertexNode;
// 图结构体
typedef struct {
VertexNode vertex[MAX_VERTEX_NUM]; // 顶点数组
int vertexNum; // 顶点数
int edgeNum; // 边数
bool isDirected; // 是否为有向图
} Graph;
// 初始化图
void initGraph(Graph *G) {
printf("请输入节点数:");
scanf("%d", &G->vertexNum);
printf("请输入边数:");
scanf("%d", &G->edgeNum);
printf("请输入图的类型(0:无向图,1:有向图):");
scanf("%d", &G->isDirected);
// 初始化顶点数组
for (int i = 0; i < G->vertexNum; i++) {
printf("请输入第%d个节点的信息:", i + 1);
scanf("%d", &G->vertex[i].data);
G->vertex[i].firstEdge = NULL;
}
// 初始化边
for (int i = 0; i < G->edgeNum; i++) {
int v1, v2, weight;
printf("请输入第%d条边(v1 v2 weight):", i + 1);
scanf("%d %d %d", &v1, &v2, &weight);
// 创建边节点
EdgeNode *e = (EdgeNode *) malloc(sizeof(EdgeNode));
e->adjvex = v2 - 1;
e->weight = weight;
e->next = G->vertex[v1 - 1].firstEdge;
G->vertex[v1 - 1].firstEdge = e;
// 如果是无向图,需要创建反向边
if (!G->isDirected) {
e = (EdgeNode *) malloc(sizeof(EdgeNode));
e->adjvex = v1 - 1;
e->weight = weight;
e->next = G->vertex[v2 - 1].firstEdge;
G->vertex[v2 - 1].firstEdge = e;
}
}
}
// 广度优先搜索
void bfs(Graph *G, int v) {
bool visited[MAX_VERTEX_NUM] = {false}; // 初始化所有节点为未访问
int queue[MAX_VERTEX_NUM]; // 定义队列
int front = 0, rear = 0; // 定义队首和队尾指针
printf("广度优先搜索结果:");
visited[v] = true;
printf("%d ", G->vertex[v].data);
queue[rear++] = v;
while (front < rear) {
int i = queue[front++]; // 出队
EdgeNode *e = G->vertex[i].firstEdge;
while (e != NULL) {
if (!visited[e->adjvex]) {
visited[e->adjvex] = true;
printf("%d ", G->vertex[e->adjvex].data);
queue[rear++] = e->adjvex; // 入队
}
e = e->next;
}
}
printf("\n");
}
// 深度优先搜索
void dfs(Graph *G, int v, bool visited[]) {
visited[v] = true;
printf("%d ", G->vertex[v].data);
EdgeNode *e = G->vertex[v].firstEdge;
while (e != NULL) {
if (!visited[e->adjvex]) {
dfs(G, e->adjvex, visited);
}
e = e->next;
}
}
// 深度优先搜索入口
void dfsEntry(Graph *G, int v) {
bool visited[MAX_VERTEX_NUM] = {false}; // 初始化所有节点为未访问
printf("深度优先搜索结果:");
dfs(G, v, visited);
printf("\n");
}
int main() {
Graph G;
initGraph(&G);
// 执行无向图的深度优先搜索
dfsEntry(&G, 0);
// 执行有向图的广度优先搜索
printf("请输入起始节点:");
int v;
scanf("%d", &v);
bfs(&G, v - 1);
return 0;
}
```
上述程序中,我们定义了三个结构体,分别表示邻接表中的边、顶点和图。在初始化图时,我们先从用户输入中读取节点数、边数和图的类型,然后依次读入每个节点的信息和每一条边的信息,并创建相应的边节点,将其插入到邻接表中。
搜索算法实现中,广度优先搜索使用了队列来实现节点的访问顺序,而深度优先搜索则使用了递归函数。
最后,在主函数中,我们先执行了无向图的深度优先搜索,然后让用户输入起始节点,执行有向图的广度优先搜索。
阅读全文