数据结构(图)的代码实现和测试(2)——广度优先搜索BFS

在实现队列的代码之后,经过调整,开始着手实现广搜BFS

我们从上篇文章数据结构(图)的代码实现和测试(1)——邻接矩阵实现和DFS之后开始说明

我们对图的遍历函数进行一些小小的改动,主要将最后测试的DFS改为BFS

void graphTraverse(Graph& G)
{
	int v;
	QueueA<int> Q;
	for (int v = 0; v < G.n(); v++)	 //预处理,将所有节点全部设置为未放问的状态,准备遍历
	{
		G.setMark(v, UNVISITED);
	}
	for (int v = 0; v < G.n(); v++)/*其实是从v = 0的顶点开始遍历,但是for循环的目的是为了检验是否遍历了所有的顶点
									如果有顶点没有被访问,则从这个顶点开始继续进行深度优先遍历	
									*/
	{
		if (G.getMark(v) == UNVISITED)
		{
			std::cout << v << std::endl;//该打印语句用于测试
			BFS(G,v,&Q);				//这个位置可以放  任意 遍历的算法,不只是DFS  BFS也可以
			//DFS(G,v);
		}
	}

}

之后来看BFS的实现

void BFS(Graph& G, int start,Queue<int> *Q)
{
	int v, w;
	
	Q->enqueue(start);        //从start节点开始遍历,先将start节点入队
	G.setMark(start, VISITED);//访问start节点并将其标记为已访问
	while (Q->length()!=0)
	{
		v = Q->dequeue();     //如果队列不为空,取一个队首的元素

		/*
			这里可以放privisit(G,v)函数,以便对访问的v节点进行处理
		*/

		std::cout << v << std::endl;        //用来检查bfs的路径
		for (int w = G.first(v); w < G.n(); w = G.next(v,w))//从这个v节点开始,遍历访问他的所有子节点
		{
			if (G.getMark(w) == UNVISITED )
			{
				G.setMark(w, VISITED);
				Q->enqueue(w);             //将访问的所有子节点放到队尾,以便最后处理
			}
		}
	}
}

我依旧按照教材中的图来测试

下面来看测试代码

test.cpp

#include"Need.h"


int main() {
	Graphm A(6);	//创建一个6个节点的图
	A.setEdge_undirected(0, 2, 2);
	A.setEdge_undirected(0, 4, 5);
	A.setEdge_undirected(4, 5, 5);
	A.setEdge_undirected(2, 3, 2);
	A.setEdge_undirected(3, 5, 1);
	A.setEdge_undirected(2, 5, 4);
	A.setEdge_undirected(5, 1, 5);
	A.setEdge_undirected(1, 2, 3);
	A.print();
	graphTraverse(A);
	//int d[6];
	//Dijkstra(&A, d, 0);
	//std::cout << std::endl;
	//printDijkstra(A, d);
	return 0;
}

另外需要注意的是,在这里我写了一个新的函数:setEdge_undirected();

这个函数是为了弥补原来的setEdge函数只能一条一条添加有向边 导致效率低下的缺点

setEdge_undirected函数可以直接在两个顶点之间添加无向边

下面是setEdge_undirected函数的实现

void Graphm::setEdge_undirected(int v1, int v2, int wt)
{
	Assert(wt > 0, "非法的权值");
	if (matrix[v1][v2] == 0 && matrix[v2][v1]==0)
	{
		numEdge++;
	}
	matrix[v1][v2] = wt;
	matrix[v2][v1] = wt;

}

测试结果如下

代表从0 2 4 1 3 5的路径进行BFS遍历

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值