代码实现内容:
①无向图的邻接表储存
②基于此存储结构的DFS BFS
/*
实现内容:
①无向图的邻接表储存实现
②DFS BFS
邻接表:顶点结构顺序存储(结构数组) 结构包含顶点信息和从该顶点出去的第一个弧节点指针
弧节点包括:下一个弧节点指针、弧依附的另一个顶点在数组的下标、弧的信息(ex:权重)
由于邻接表存储方式的问题,在DFS时想要左边先遍历,必须要在给边标号的时候,对于同一个顶点,
右侧边的序号大于左侧边的序号
VS2019编译通过 2020.7.15 王大花
*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <memory.h>
#define ALGraphType char
#define Max_Vertices 100
typedef enum GRAKIND { DG, UG, DN, UN } GraKind;
//储存边的结构 弧节点
typedef struct ARCNODE ArcNode;
typedef struct ARCNODE {
int Adjvex;
ArcNode* Next;
}ArcNode;
//图的顶点定义
typedef struct VNODE {
ALGraphType Date;
ArcNode* FirstArc;
}VNode;
typedef struct ALGRAPH {
VNode* Vertices;
int Vexnum, Arcnum; //顶点数目、边的数目
GraKind Kind;
}ALGraph;
//BFS辅助队列
//为了简化,用顺序表实现
typedef struct QUEUE {
int Vertices[Max_Vertices];
int Head, Tail;
}Queue;
//初始化队列
void Inite_Queue(Queue* Q) {
Q->Head = Q->Tail = 0;
}
//根据顶点信息,找到顶点在顺序存储的位置(默认顶点按照字母顺序编号)
int Locate(ALGraphType ch) {
return toupper(ch) - 'A';
}
//创建图
void Creat_ALGraph(ALGraph* G) {
if (NULL == G)
return;
printf("请输入顶点数目:");
scanf("%d", &G->Vexnum);
G->Vertices = (VNode*)malloc(sizeof(VNode) * G->Vexnum);
printf("请输入边的数目:");
scanf("%d", &G->Arcnum);
//录入顶点信息
for (int i = 0; i < G->Vexnum; i++) {
printf("请输入第%d个顶点的信息:", i + 1);
//不读回车
rewind(stdin);
scanf("%c", &G->Vertices[i].Date);
G->Vertices[i].FirstArc = NULL;
}
//录入每个边的信息(默认顶点按照ABCD编号)
for (int i = 0; i < G->Arcnum; i++) {
//不读回车
rewind(stdin);
char ch1, ch2;
ArcNode* p = (ArcNode*)malloc(sizeof(ArcNode));
if (NULL == p)
exit(EXIT_FAILURE);
printf("请输入第%d条边依附的顶点:", i + 1);
//不读回车
rewind(stdin);
//默认输入格式为X Y
scanf("%c %c", &ch1, &ch2);
//更新ch1结点
p->Adjvex = Locate(ch2);
p->Next = G->Vertices[Locate(ch1)].FirstArc;
G->Vertices[Locate(ch1)].FirstArc = p;
//更新ch2结点
p = (ArcNode*)malloc(sizeof(ArcNode));
if (NULL == p)
exit(EXIT_FAILURE);
p->Adjvex = Locate(ch1);
p->Next = G->Vertices[Locate(ch2)].FirstArc;
G->Vertices[Locate(ch2)].FirstArc = p;
}
}
void Visit(ALGraph G, int v) {
printf("%c\t", G.Vertices[v].Date);
}
void DFS(ALGraph G, int v, int* Visited) {
Visited[v] = 1;
Visit(G, v);
while (NULL != G.Vertices[v].FirstArc) {
if (!Visited[G.Vertices[v].FirstArc->Adjvex])
DFS(G, G.Vertices[v].FirstArc->Adjvex, Visited);
G.Vertices[v].FirstArc = G.Vertices[v].FirstArc->Next;
}
}
void DFS_Traverse(ALGraph G) {
int* Visited = (int*)malloc(sizeof(int) * G.Vexnum);
memset(Visited, 0, sizeof(int) * G.Vexnum);
printf("\nDFS的结果为:\t");
for (int i = 0; i < G.Vexnum; i++) {
if (!Visited[i])
DFS(G, i, Visited);
}
}
void BFS_Traverse(ALGraph G) {
//辅助队列
Queue Q;
Inite_Queue(&Q);
//记录是否被访问过
int* Visited = (int*)malloc(sizeof(int) * G.Vexnum);
memset(Visited, 0, sizeof(int) * G.Vexnum);
printf("\nBFS的结果为:\t");
for (int i = 0; i < G.Vexnum; i++) {
if (!Visited[i]) {
Visited[i] = 1;
Visit(G, i);
Q.Vertices[Q.Tail++] = i;
while (Q.Head != Q.Tail) {
//所有和队头顶点直接相连还未访问的顶点入队
while (NULL != G.Vertices[Q.Vertices[Q.Head]].FirstArc && !Visited[G.Vertices[Q.Vertices[Q.Head]].FirstArc->Adjvex]){
Visited[G.Vertices[Q.Vertices[Q.Head]].FirstArc->Adjvex] = 1;
Visit(G, G.Vertices[Q.Vertices[Q.Head]].FirstArc->Adjvex);
Q.Vertices[Q.Tail++] = G.Vertices[Q.Vertices[Q.Head]].FirstArc->Adjvex;
G.Vertices[Q.Vertices[Q.Head]].FirstArc = G.Vertices[Q.Vertices[Q.Head]].FirstArc->Next;
}
Q.Head++;
}//while
}//if
}//for
}
int main() {
ALGraph G;
Creat_ALGraph(&G);
DFS_Traverse(G);
BFS_Traverse(G);
return 0;
}
运行情况:以下图为例(所有顶点改为ABCD……边上方数字是序号)
PS:课本P168图
(注意在输入顶点的时候中间有空格ex:A B)