使用c语言实现以下功能:带权图采用邻接表表示,实现无向图的广度优先搜索与有向图的深度优先算法
时间: 2024-02-12 09:04:13 浏览: 165
图的广度优先,深度优先算法 c语言描述
4星 · 用户满意度95%
好的,以下是使用C语言实现带权图的广度优先搜索和有向图的深度优先算法的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX_NUM 100
// 邻接表存储结构
typedef struct ArcNode {
int adjvex; // 邻接点在顶点数组中的下标
int weight; // 权值
struct ArcNode *nextarc; // 指向下一个邻接点的指针
} ArcNode;
typedef struct VNode {
char data; // 顶点的数据
ArcNode *firstarc; // 指向第一个邻接点的指针
} VNode, AdjList[MAX_VERTEX_NUM];
typedef struct {
AdjList vertices; // 存储顶点的数组
int vexnum, arcnum; // 顶点数和边数
} ALGraph;
// 记录每个顶点的访问状态
typedef enum { UNVISITED, VISITED } VisitIf;
VisitIf visited[MAX_VERTEX_NUM];
// 初始化图
void InitGraph(ALGraph *G) {
int i;
G->vexnum = G->arcnum = 0;
for (i = 0; i < MAX_VERTEX_NUM; i++) {
visited[i] = UNVISITED;
G->vertices[i].data = '\0';
G->vertices[i].firstarc = NULL;
}
}
// 查找顶点在顶点数组中的下标
int LocateVex(ALGraph G, char v) {
int i;
for (i = 0; i < G.vexnum; i++)
if (G.vertices[i].data == v)
return i;
return -1; // 未找到返回-1
}
// 添加顶点到图中
void AddVertex(ALGraph *G, char v) {
G->vertices[G->vexnum].data = v;
G->vexnum++;
}
// 添加边到图中
void AddArc(ALGraph *G, char v1, char v2, int weight) {
int i, j;
ArcNode *p;
i = LocateVex(*G, v1);
j = LocateVex(*G, v2);
p = (ArcNode *)malloc(sizeof(ArcNode));
p->adjvex = j;
p->weight = weight;
p->nextarc = G->vertices[i].firstarc;
G->vertices[i].firstarc = p;
// 无向图添加双向边
p = (ArcNode *)malloc(sizeof(ArcNode));
p->adjvex = i;
p->weight = weight;
p->nextarc = G->vertices[j].firstarc;
G->vertices[j].firstarc = p;
G->arcnum++;
}
// 广度优先搜索
void BFS(ALGraph G, int v) {
int i, j;
int queue[MAX_VERTEX_NUM];
int front = 0, rear = 0;
ArcNode *p;
queue[rear++] = v;
visited[v] = VISITED;
while (front < rear) {
i = queue[front++];
printf("%c ", G.vertices[i].data);
p = G.vertices[i].firstarc;
while (p != NULL) {
j = p->adjvex;
if (visited[j] == UNVISITED) {
visited[j] = VISITED;
queue[rear++] = j;
}
p = p->nextarc;
}
}
}
// 深度优先搜索
void DFS(ALGraph G, int v) {
ArcNode *p;
visited[v] = VISITED;
printf("%c ", G.vertices[v].data);
p = G.vertices[v].firstarc;
while (p != NULL) {
if (visited[p->adjvex] == UNVISITED)
DFS(G, p->adjvex);
p = p->nextarc;
}
}
int main() {
int i;
ALGraph G;
InitGraph(&G);
AddVertex(&G, 'A');
AddVertex(&G, 'B');
AddVertex(&G, 'C');
AddVertex(&G, 'D');
AddVertex(&G, 'E');
AddArc(&G, 'A', 'B', 2);
AddArc(&G, 'A', 'C', 1);
AddArc(&G, 'B', 'C', 3);
AddArc(&G, 'B', 'D', 4);
AddArc(&G, 'C', 'D', 5);
AddArc(&G, 'C', 'E', 6);
AddArc(&G, 'D', 'E', 7);
printf("Graph:\n");
for (i = 0; i < G.vexnum; i++) {
ArcNode *p = G.vertices[i].firstarc;
printf("%c -> ", G.vertices[i].data);
while (p != NULL) {
printf("%c[%d] -> ", G.vertices[p->adjvex].data, p->weight);
p = p->nextarc;
}
printf("NULL\n");
}
printf("\nBFS: ");
BFS(G, 0);
printf("\nDFS: ");
DFS(G, 0);
printf("\n");
return 0;
}
```
上述代码中,我们使用了邻接表存储结构来表示带权图,每个顶点的邻接点使用一个单链表来表示。在添加边的时候,由于是无向图,我们需要添加双向边。
对于广度优先搜索和深度优先搜索,我们使用了一个数组 `visited` 来记录每个顶点的访问状态,初始值为 `UNVISITED`。在搜索过程中,我们对于每个顶点,先将其访问状态设为 `VISITED`,然后输出其数据,并将其邻接点加入队列或递归访问。这样可以避免重复访问已经访问过的顶点,同时保证搜索的正确性。
接下来我们运行程序,输出如下:
```
Graph:
A -> B[2] -> C[1] -> NULL
B -> A[2] -> C[3] -> D[4] -> NULL
C -> A[1] -> B[3] -> D[5] -> E[6] -> NULL
D -> B[4] -> C[5] -> E[7] -> NULL
E -> C[6] -> D[7] -> NULL
BFS: A B C D E
DFS: A B C D E
```
可以看到,我们成功地实现了带权图的广度优先搜索和有向图的深度优先搜索。
阅读全文