C语言无向图的邻接表储存以及DFS、BFS的实现

代码实现内容:
①无向图的邻接表储存
②基于此存储结构的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)
在这里插入图片描述

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值