栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

图的深度优先搜索与广度优先搜索

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

图的深度优先搜索与广度优先搜索

图的深度优先搜索DFS与广度优先搜索BFS
#include
#include
//#include

#define INFINITY INT_MAX		// 无穷大
#define INITIAL_VALUE INFINITY	// 邻接矩阵初始值
#define INITIAL_PRINT "∞"		// 定义初始值的打印值
#define MaxVertexNum 20		// 邻接矩阵最大顶点数
#define OVERFLOW -2			// 空间分配失败、溢出
// 邻接矩阵
typedef char VertexType;
typedef int EdgeType;
typedef int InfoType;
typedef struct {
	VertexType Vex[MaxVertexNum];	// 顶点表
	EdgeType Edge[MaxVertexNum][MaxVertexNum];	// 边表(邻接矩阵)
	int vexnum, arcnum;		// 顶点数、边数
}MGraph;

// 邻接表
typedef struct ArcNode {	// 边表结点
	int adjvex;				// 该弧所指向的顶点的位置(下标)
	struct ArcNode* next;	// 指向下一条弧的指针
	InfoType info;			//权值
}ArcNode;
typedef struct VNode {	// 顶点表结点
	VertexType data;	// 顶点信息
	ArcNode* first;		// 指向第一条依附于此顶点的弧的指针
}VNode, AdjList[MaxVertexNum];
typedef struct {		// 邻接表
	AdjList vertices;	// 一维数组的顶点表,各顶点结点内又放置了一个单链表的边表头指针
	int vexnum, arcnum;	// 图的顶点数和弧数
}ALGraph;


// 返回图的邻接矩阵存储结构中值为v的顶点下标
int LocateVex(MGraph G, VertexType v);
// 创建带权图(网)的邻接矩阵存储结构 flag为true时创建有向图,flag为false时创建无向图
void createMGraph(MGraph& G, bool flag);
// 返回图的邻接表中值为v的顶点下标
int LocateVex(ALGraph G, VertexType v);
// 创建带权图的邻接表存储结构 flag为true时创建有向图,为false时创建无向图
void createALGraph(ALGraph& G, bool flag);
// 从图的邻接表表示转换为邻接矩阵表示
MGraph ALGraphToMGraph(ALGraph algraph);
void printMGraph(MGraph G);

// 定义访问的行为
void visit(VertexType name);
int FirstNeighbor(MGraph G, int v);
int NextNeighbor(MGraph G, int v, int w);

// 广度优先搜索
void BFSTraverse(MGraph G);
void BFS(MGraph G, int v);

// 深度优先搜索
void DFSTraverse(MGraph G);
void DFS(MGraph G, int v);

// 返回图的邻接矩阵存储结构中值为v的顶点下标
int LocateVex(MGraph G, VertexType v) {
	for (int i = 0; i < G.vexnum; i++) {
		if (G.Vex[i] == v) return i;
	}
	return -1;
}

// 创建带权图(网)的邻接矩阵存储结构 flag为true时创建有向图,flag为false时创建无向图
void createMGraph(MGraph& G, bool flag) {
	scanf("%d %d", &G.vexnum, &G.arcnum);	// 首先输入顶点数和边数
	// 输入各顶点字母
	for (int i = 0; i < G.vexnum; i++) scanf(" %c", &G.Vex[i]);
	// 初始化邻接矩阵
	for (int i = 0; i < G.vexnum; i++) {
		for (int j = 0; j < G.vexnum; j++) {
			G.Edge[i][j] = INITIAL_VALUE;
		}
	}
	// 构造邻接矩阵
	for (int k = 0; k < G.arcnum; k++) {
		VertexType v1, v2;	// 顶点
		EdgeType w;	// 权值
		scanf(" %c %c %d", &v1, &v2, &w);	// 输入一条边及其权值
											// 定位v1和v2在邻接矩阵中的位置
		int i = LocateVex(G, v1), j = LocateVex(G, v2);
		G.Edge[i][j] = w;
		if (flag == false) // 若创建无向图,则对称位置也设置为此值
			G.Edge[j][i] = w;
	}
}

// 返回图的邻接表中值为v的顶点下标
int LocateVex(ALGraph G, VertexType v) {
	for (int i = 0; i < G.vexnum; i++) {
		if (G.vertices[i].data == v) return i;
	}
	return -1;
}

// 创建带权图的邻接表存储结构 flag为true时创建有向图,为false时创建无向图
void createALGraph(ALGraph& G, bool flag) {
	scanf("%d %d", &G.vexnum, &G.arcnum);	// 首先输入顶点数和边数
											// 输入各顶点字母,构造表头向量
	for (int i = 0; i < G.vexnum; i++) {
		scanf(" %c", &G.vertices[i].data);
		G.vertices[i].first = NULL;	// 初始化边表头指针
	}
	// 构造边表
	for (int k = 0; k < G.arcnum; k++) {
		VertexType v1, v2; InfoType info;
		scanf(" %c %c %d", &v1, &v2, &info);	// 输入一条边及其权值
		int i = LocateVex(G, v1), j = LocateVex(G, v2);
		ArcNode* p;
		if (!(p = (ArcNode*)malloc(sizeof(ArcNode)))) exit(OVERFLOW);
		p->adjvex = j; p->info = info;
		// 采用头插法
		p->next = G.vertices[i].first;
		G.vertices[i].first = p;
		if (flag == false) {	// 若为无向图,则在另一个顶点处也加入该边
			ArcNode* q;
			if (!(q = (ArcNode*)malloc(sizeof(ArcNode)))) exit(OVERFLOW);
			q->adjvex = i; q->info = info;
			// 采用头插法
			q->next = G.vertices[j].first;
			G.vertices[j].first = q;
		}
	}
}

// 从图的邻接表表示转换为邻接矩阵表示
MGraph ALGraphToMGraph(ALGraph algraph) {
	// 先初始化邻接矩阵所有元素,然后遍历邻接表顶点表每一行,直接填写相应邻接矩阵元素值
	MGraph res;
	res.vexnum = algraph.vexnum;
	res.arcnum = algraph.arcnum;
	// 初始化邻接表元素为0
	for (int i = 0; i < res.vexnum; i++) {
		for (int j = 0; j < res.vexnum; j++) {
			res.Edge[i][j] = INITIAL_VALUE;
		}
	}
	for (int i = 0; i < res.vexnum; i++) {
		VNode vv = algraph.vertices[i];
		res.Vex[i] = vv.data;	// 顶点赋值
		// 遍历边表
		ArcNode* t = vv.first;
		while (t != NULL) {	// 邻接矩阵赋值
			int j = t->adjvex;
			res.Edge[i][j] = t->info;
			t = t->next;
		}
	}
	return res;
}

void printMGraph(MGraph G)
{
	for (int i = 0; i < G.vexnum; i++) {
		for (int j = 0; j < G.vexnum; j++) {
			if (G.Edge[i][j] == INITIAL_VALUE) {
				printf("%st", INITIAL_PRINT);
			}
			else {
				printf("%dt", G.Edge[i][j]);
			}
			
		}
		printf("n");
	}
}

bool visited[MaxVertexNum];	// 访问标记数组

void visit(VertexType name) {
	printf("%c ", name);
}

int FirstNeighbor(MGraph G, int v)
{
	return NextNeighbor(G, v, -1);
}

int NextNeighbor(MGraph G, int v, int w)
{
	for (int i = w+1; i < G.vexnum; i++) {
		if (G.Edge[v][i] != INITIAL_VALUE) {
			return i;
		}
	}
	return -1;	// 返回小于0的值,说明找不到
}


// 广度优先搜索
void BFSTraverse(MGraph G)
{
	// 先初始化标记数组
	for (int i = 0; i < G.vexnum; i++)	visited[i] = false;
	
	for (int i = 0; i < G.vexnum; i++) {
		if (!visited[i])
			BFS(G, i);
	}
}

// 非递归广度优先算法
void BFS(MGraph G, int v)
{
	visit(G.Vex[v]);	// 访问初始顶点
	visited[v] = true;	// 置该点为访问了
	VertexType queue[MaxVertexNum];	int front = -1, rear = -1;  // 辅助队列Q
	rear = (rear + 1) % MaxVertexNum; queue[rear] = v;	// 顶点入队列
	while (rear != front) {	// 队列非空
		front = (front + 1) % MaxVertexNum; v = queue[front];// 队头出队列
		// 检测v的所有邻接点
		for (int w = FirstNeighbor(G, v); w >= 0; w = NextNeighbor(G, v, w)) {	// 查找失败时w = -1
			if (!visited[w]) {
				visit(G.Vex[w]);
				visited[w] = true;
				rear = (rear + 1) % MaxVertexNum; queue[rear] = w;	// 顶点入队列
			}
		}
	}
}


// 深度优先搜索
void DFSTraverse(MGraph G)
{
	// 初始化标记数组
	for (int v = 0; v < G.vexnum; v++) {
		visited[v] = false;
	}
	for (int v = 0; v < G.vexnum; v++) {
		if (!visited[v])
			DFS(G, v);
	}
}

// 递归算法
void DFS(MGraph G, int v) {
	visit(G.Vex[v]);
	visited[v] = true;
	// 检测v的所有邻接点
	for (int w = FirstNeighbor(G, v); w >= 0; w = NextNeighbor(G, v, w)) {	// 查找失败时w = -1
		if (!visited[w]) {
			DFS(G, w);
		}
	}
}

int main(char* argv[]) {
	
	MGraph G;
	createMGraph(G, true);
	printMGraph(G);
	printf("广度优先搜索:n");
	BFSTraverse(G); printf("n");
	printf("深度优先搜索:n");
	DFSTraverse(G); printf("n");
	//ALGraph G2;
	//createALGraph(G2, true);

	//MGraph G = ALGraphToMGraph(G2);

	
	MGraph G2;
	createMGraph(G2, false);
	printMGraph(G2);
	printf("广度优先搜索:n");
	BFSTraverse(G2); printf("n");
	printf("深度优先搜索:n");
	DFSTraverse(G2); printf("n");


	printf("Finishn");
	return 0;
}

测试图

运行效果

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/957715.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号