第1关:图的邻接表表示法
#include <stdio.h>
#include <stdlib.h>
#define MVNum 100 // 最大顶点数
typedef char VerTexType; // 顶点信息
typedef int OtherInfo; // 和边相关的信息
// - - - - -图的邻接表存储表示- - - - -
typedef struct ArcNode { // 边结点
int adjvex; // 该边所指向的顶点的位置
struct ArcNode* nextarc; // 指向下一条边的指针
OtherInfo info; // 和边相关的信息
} ArcNode;
typedef struct VNode {
VerTexType data; // 顶点信息
ArcNode* firstarc; // 指向第一条依附该顶点的边的指针
} VNode, AdjList[MVNum]; // AdjList表示邻接表类型
typedef struct {
AdjList vertices; // 邻接表
int vexnum, arcnum; // 图的当前顶点数和边数
} ALGraph;
// 确定点v在G中的位置
int LocateVex(ALGraph G, VerTexType v) {
for (int i = 0; i < G.vexnum; i++) {
if (G.vertices[i].data == v) {
return i;
}
}
return -1;
}
// 创建无向图函数CreateUDG
void CreateUDG(ALGraph* G) {
int i, j, k;
VerTexType v1, v2;
//printf("请输入总顶点数,总边数:\n");
scanf("%d %d\n", &G->vexnum, &G->arcnum);
//printf("输入顶点的信息:\n");
for (i = 0; i < G->vexnum; i++) {
scanf("%c\n", &G->vertices[i].data);
G->vertices[i].firstarc = NULL; // 初始化边链表
}
//printf("输入每条边依附的两个顶点:\n");
for (k = 0; k < G->arcnum; k++) {
scanf("%c %c\n", &v1, &v2);
i = LocateVex(*G, v1);
j = LocateVex(*G, v2);
// 为v1创建边结点
ArcNode* p1 = (ArcNode*)malloc(sizeof(ArcNode));
p1->adjvex = j;
p1->nextarc = G->vertices[i].firstarc;
G->vertices[i].firstarc = p1;
// 为v2创建边结点 (因为是无向图,双向添加)
ArcNode* p2 = (ArcNode*)malloc(sizeof(ArcNode));
p2->adjvex = i;
p2->nextarc = G->vertices[j].firstarc;
G->vertices[j].firstarc = p2;
}
}
int main() {
ALGraph G;
int i;
CreateUDG(&G);
printf("*****邻接表表示法创建的无向网*****\n");
for (i = 0; i < G.vexnum; ++i) {
VNode temp = G.vertices[i];
ArcNode* p = temp.firstarc;
if (p == NULL) {
printf("%c\n", G.vertices[i].data);
}
else {
printf("%c", temp.data);
while (p) {
printf("->%d", p->adjvex);
p = p->nextarc;
}
}
printf("\n");
}
return 0;
}
第2关:采用邻接表表示图的深度优先搜索遍历
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MVNum 100
typedef char VerTexType;
typedef int OtherInfo;
typedef struct ArcNode {
int adjvex;
struct ArcNode* nextarc;
OtherInfo info;
} ArcNode;
typedef struct VNode {
VerTexType data;
ArcNode* firstarc;
} VNode, AdjList[MVNum];
typedef struct {
AdjList vertices;
int vexnum, arcnum;
} ALGraph;
bool visited[MVNum];
int LocateVex(ALGraph G, VerTexType v) {
for (int i = 0; i < G.vexnum; i++) {
if (G.vertices[i].data == v) {
return i;
}
}
return -1;
}
void CreateUDG(ALGraph* G) {
int i, j, k;
VerTexType v1, v2;
scanf("%d %d\n", &G->vexnum, &G->arcnum);
for (i = 0; i < G->vexnum; i++) {
scanf("%c\n", &G->vertices[i].data);
G->vertices[i].firstarc = NULL;
}
for (k = 0; k < G->arcnum; k++) {
scanf("%c %c\n", &v1, &v2);
i = LocateVex(*G, v1);
j = LocateVex(*G, v2);
ArcNode* p1 = (ArcNode*)malloc(sizeof(ArcNode));
p1->adjvex = j;
p1->nextarc = G->vertices[i].firstarc;
G->vertices[i].firstarc = p1;
ArcNode* p2 = (ArcNode*)malloc(sizeof(ArcNode));
p2->adjvex = i;
p2->nextarc = G->vertices[j].firstarc;
G->vertices[j].firstarc = p2;
}
}
void DFS_AL(ALGraph G, int v) {
printf("%c ", G.vertices[v].data);
visited[v] = true;
ArcNode* p = G.vertices[v].firstarc;
while (p) {
if (!visited[p->adjvex]) {
DFS_AL(G, p->adjvex);
}
p = p->nextarc;
}
}
int main() {
ALGraph G;
int i;
CreateUDG(&G);
VerTexType c;
scanf("%c\n", &c);
for (i = 0; i < G.vexnum; ++i) {
if (c == G.vertices[i].data) {
break;
}
}
while (i >= G.vexnum) {
printf("该点不存在,请重新输入!\n");
scanf("%c\n", &c);
for (i = 0; i < G.vexnum; ++i) {
if (c == G.vertices[i].data) {
break;
}
}
}
printf("深度优先搜索遍历图结果:\n");
for (int j = 0; j < G.vexnum; j++) {
visited[j] = false;
}
DFS_AL(G, i);
printf("\n");
return 0;
}
第3关:采用邻接表表示图的广度优先搜索遍历
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MVNum 100 // 最大顶点数
#define MAXQSIZE 100 // 最大队列长度
typedef char VerTexType; // 顶点信息
typedef int ArcType; // 假设边的权值类型为整型
typedef int OtherInfo; // 和边相关的信息
// - - - - -图的邻接表存储表示- - - - -
typedef struct ArcNode { // 边结点
int adjvex; // 该边所指向的顶点的位置
struct ArcNode *nextarc; // 指向下一条边的指针
OtherInfo info; // 和边相关的信息
} ArcNode;
typedef struct VNode {
VerTexType data; // 顶点信息
ArcNode *firstarc; // 指向第一条依附该顶点的边的指针
} VNode, AdjList[MVNum]; // AdjList表示邻接表类型
typedef struct {
AdjList vertices; // 邻接表
int vexnum, arcnum; // 图的当前顶点数和边数
} ALGraph;
bool visited[MVNum]; // 访问标志数组,其初值为"false"
// ----队列的定义及操作--------
typedef struct {
ArcType *base; // 初始化的动态分配存储空间
int front; // 头指针,若队列不空,指向队头元素
int rear; // 尾指针,若队列不空,指向队尾元素的下一个位置
} sqQueue;
void InitQueue(sqQueue *Q) {
Q->base = (ArcType *)malloc(MAXQSIZE * sizeof(ArcType));
if (!Q->base) exit(0); // 存储分配失败
Q->front = Q->rear = 0; // 初始化为空队列
}
void EnQueue(sqQueue *Q, ArcType e) {
if ((Q->rear + 1) % MAXQSIZE == Q->front) return; // 队列满
Q->base[Q->rear] = e;
Q->rear = (Q->rear + 1) % MAXQSIZE;
}
bool QueueEmpty(sqQueue Q) {
return Q.front == Q.rear;
}
void DeQueue(sqQueue *Q, ArcType *u) {
if (Q->front == Q->rear) return; // 队列空
*u = Q->base[Q->front];
Q->front = (Q->front + 1) % MAXQSIZE;
}
int LocateVex(ALGraph G, VerTexType v) {
for (int i = 0; i < G.vexnum; i++) {
if (G.vertices[i].data == v) {
return i;
}
}
return -1;
}
void CreateUDG(ALGraph *G) {
int i, j, k;
VerTexType v1, v2;
printf("请输入总顶点数,总边数:\n");
scanf("%d %d\n", &G->vexnum, &G->arcnum);
printf("输入顶点的信息:\n");
for (i = 0; i < G->vexnum; i++) {
scanf("%c\n", &G->vertices[i].data);
G->vertices[i].firstarc = NULL; // 初始化边链表
}
printf("输入每条边依附的两个顶点:\n");
for (k = 0; k < G->arcnum; k++) {
scanf("%c %c\n", &v1, &v2);
i = LocateVex(*G, v1);
j = LocateVex(*G, v2);
// 为v1创建边结点
ArcNode *p1 = (ArcNode *)malloc(sizeof(ArcNode));
p1->adjvex = j;
p1->nextarc = G->vertices[i].firstarc;
G->vertices[i].firstarc = p1;
// 为v2创建边结点 (因为是无向图,双向添加)
ArcNode *p2 = (ArcNode *)malloc(sizeof(ArcNode));
p2->adjvex = i;
p2->nextarc = G->vertices[j].firstarc;
G->vertices[j].firstarc = p2;
}
}
void BFS(ALGraph G, int v) {
sqQueue Q;
InitQueue(&Q);
printf("%c ", G.vertices[v].data); // 访问该顶点
visited[v] = true; // 标记已访问
EnQueue(&Q, v);
while (!QueueEmpty(Q)) {
int u;
DeQueue(&Q, &u); // 队头元素出队
ArcNode *p = G.vertices[u].firstarc;
while (p) {
if (!visited[p->adjvex]) {
printf("%c ", G.vertices[p->adjvex].data); // 访问该顶点
visited[p->adjvex] = true; // 标记已访问
EnQueue(&Q, p->adjvex); // 入队
}
p = p->nextarc;
}
}
}
int main() {
ALGraph G;
int i;
CreateUDG(&G); // 调用创建无向图函数CreateUDG
VerTexType c;
scanf("%c\n", &c);
for (i = 0; i < G.vexnum; ++i) {
if (c == G.vertices[i].data) {
break;
}
}
while (i >= G.vexnum) {
printf("该点不存在,请重新输入!\n");
printf("请输入遍历连通图的起始点:");
scanf("%c\n", &c);
for (i = 0; i < G.vexnum; ++i) {
if (c == G.vertices[i].data) {
break;
}
}
}
printf("广度优先搜索遍历图结果:\n");
for (int j = 0; j < G.vexnum; j++) {
visited[j] = false; // 确保访问标志数组在遍历前被重置
}
BFS(G, i); // 调用广度优先搜索遍历图函数BFS
printf("\n");
return 0;
}