用c语言以邻接表作为图的存储结构,实现无向图的深度优先和广度优先遍历的完整代码,代码中包括以邻接表的形式创建无向图,返回一个位置的第一个邻接顶点,返回一个位置的相对于第一个邻接顶点的下一个邻接顶点的函数的代码
时间: 2024-01-22 16:19:17 浏览: 63
以下是用C语言以邻接表作为图的存储结构,实现无向图的深度优先和广度优先遍历的完整代码:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX_NUM 20 // 最大顶点数
typedef struct ArcNode {
int adjvex; // 该边的终点位置
struct ArcNode *next; // 指向下一条边的指针
} ArcNode;
typedef struct VNode {
char data; // 顶点的值
ArcNode *firstArc; // 指向第一条依附该顶点的边的指针
} VNode, AdjList[MAX_VERTEX_NUM];
typedef struct {
AdjList vertices; // 图中所有顶点的邻接表
int vexNum, arcNum; // 图的当前顶点数和边数
} ALGraph;
/* 创建无向图的邻接表存储结构 */
void createALGraph(ALGraph *G) {
printf("请输入顶点数和边数:");
scanf("%d%d", &G->vexNum, &G->arcNum);
// 初始化每个顶点的邻接表为空表
for (int i = 0; i < G->vexNum; i++) {
G->vertices[i].data = 'A' + i;
G->vertices[i].firstArc = NULL;
}
// 逐条读入边并建立邻接表
for (int k = 0; k < G->arcNum; k++) {
printf("请输入第%d条边的两个端点:", k + 1);
char v1, v2; // 两个端点的值
scanf(" %c%c", &v1, &v2); // 注意要在%c前面加一个空格,以吸收缓存区中的回车符
// 找到两个端点在邻接表中的位置
int i, j;
for (i = 0; i < G->vexNum; i++) {
if (G->vertices[i].data == v1) {
break;
}
}
for (j = 0; j < G->vexNum; j++) {
if (G->vertices[j].data == v2) {
break;
}
}
// 将顶点j插入顶点i的邻接表中,表示存在边<i, j>
ArcNode *node_j = (ArcNode *) malloc(sizeof(ArcNode)); // 创建一个新节点
node_j->adjvex = j;
node_j->next = G->vertices[i].firstArc; // 插入到表头
G->vertices[i].firstArc = node_j;
// 将顶点i插入顶点j的邻接表中,表示存在边<j, i>
ArcNode *node_i = (ArcNode *) malloc(sizeof(ArcNode)); // 创建一个新节点
node_i->adjvex = i;
node_i->next = G->vertices[j].firstArc; // 插入到表头
G->vertices[j].firstArc = node_i;
}
}
/* 获取一个顶点的第一个邻接顶点的位置 */
int getFirstArc(ALGraph *G, int v) {
if (G->vertices[v].firstArc != NULL) {
return G->vertices[v].firstArc->adjvex;
} else {
return -1;
}
}
/* 获取一个顶点的相对于第一个邻接顶点的下一个邻接顶点的位置 */
int getNextArc(ALGraph *G, int v, int w) {
ArcNode *p = G->vertices[v].firstArc;
while (p != NULL && p->adjvex != w) {
p = p->next;
}
if (p != NULL && p->next != NULL) {
return p->next->adjvex;
} else {
return -1;
}
}
/* 从顶点v开始深度优先遍历图 */
void DFS(ALGraph *G, int v, int *visited) {
visited[v] = 1;
printf("%c ", G->vertices[v].data); // 打印该顶点的值
for (int w = getFirstArc(G, v); w >= 0; w = getNextArc(G, v, w)) {
if (!visited[w]) {
DFS(G, w, visited); // 对未访问过的邻接顶点递归调用DFS
}
}
}
/* 深度优先遍历图 */
void DFSTraverse(ALGraph *G) {
int visited[MAX_VERTEX_NUM] = {0}; // 初始化所有顶点为未访问
for (int i = 0; i < G->vexNum; i++) {
if (!visited[i]) {
DFS(G, i, visited); // 对未访问过的顶点调用DFS
}
}
}
/* 从顶点v开始广度优先遍历图 */
void BFS(ALGraph *G, int v, int *visited) {
int queue[MAX_VERTEX_NUM], front = 0, rear = 0; // 初始化队列
visited[v] = 1;
printf("%c ", G->vertices[v].data); // 打印该顶点的值
queue[rear++] = v; // 将该顶点入队
while (front < rear) {
int w = queue[front++]; // 取出队首顶点
for (int x = getFirstArc(G, w); x >= 0; x = getNextArc(G, w, x)) {
if (!visited[x]) {
visited[x] = 1;
printf("%c ", G->vertices[x].data); // 打印该顶点的值
queue[rear++] = x; // 将该顶点入队
}
}
}
}
/* 广度优先遍历图 */
void BFSTraverse(ALGraph *G) {
int visited[MAX_VERTEX_NUM] = {0}; // 初始化所有顶点为未访问
for (int i = 0; i < G->vexNum; i++) {
if (!visited[i]) {
BFS(G, i, visited); // 对未访问过的顶点调用BFS
}
}
}
int main() {
ALGraph G;
createALGraph(&G);
printf("深度优先遍历结果:");
DFSTraverse(&G);
printf("\n广度优先遍历结果:");
BFSTraverse(&G);
printf("\n");
return 0;
}
```
阅读全文