BFS广度优先遍历详解

                                                                          广度优先遍历

                                                                                                         ---一石激起千层浪

和深度优先遍历一样,广度优先遍历也是一种常用的搜索算法,它并没有固定的代码格式,只是一种遍历方式的思想。广度优先遍历一般用于求最短路径问题,我们用一个社交图来举例。

上图是一个无向图,用0表示两个人不是朋友,大于0值表示两个人是朋友关系,要求遍历出zzx的所有的朋友 

 广度优先遍历是以给定点为起始点,一圈一圈的遍历相关的所有点,和DFS不同的是,它整体遍历完相关所有的点然后才会去遍历下一层。所有的遍历完之后就能得到最短路径。

我们来分析社会关系图代码,首先要将与给定名称是朋友的所有名称入队列,借助队列的先进先出特性,与zzx直接相关的朋友会先进入队列,它的朋友再将朋友带入队列,这样产生的效果形象的来说就是一圈一圈的去遍历。

首先需要队列和一个标记数组,有时候队列里面需要存放的不一定是整形,也有可能是结构体或者是类。

        void GFS(const V & val)
	{
		queue<int> qu;
		vector<bool> flag(m_v.size(), false);
    
    }        

将名称对应的下标入队列。 

        void GFS(const V & val)
	{
		queue<int> qu;
		vector<bool> flag(m_v.size(), false);
		int ret = GetVertexIndex(val);

		qu.push(ret);
        }

接下来我们做的动作都是重复性的,即在队列不为空的前提下,访问队头的元素,保存队头元素的下标,然后将队头元素出队,将队头元素的朋友入队列。

                while (!qu.empty())
		{
			int index = qu.front();
			//printf("[%d,%s]", qu.front(), m_v[qu.front()]);
			/* 应对成环的情况 */
			if (flag[index]==false)
			{
				cout << qu.front() << m_v[index].c_str() << "->";
			}
			flag[index] = true;

			qu.pop();

			//将我的朋友入队
			for (int i=0;i<m_v.size();++i)
			{
				if (m_edges[index][i]!=0 && flag[i]==false)
				{
					qu.push(i);

				}
			}
		}

完整代码:

            void GFS(const V & val)
	{
		queue<int> qu;
		vector<bool> flag(m_v.size(), false);
		int ret = GetVertexIndex(val);

		qu.push(ret);

		while (!qu.empty())
		{
			int index = qu.front();
			//printf("[%d,%s]", qu.front(), m_v[qu.front()]);
			/* 应对成环的情况 */
			if (flag[index]==false)
			{
				cout << qu.front() << m_v[index].c_str() << "->";
			}
			flag[index] = true;

			qu.pop();

			//将我的朋友入队
			for (int i=0;i<m_v.size();++i)
			{
				if (m_edges[index][i]!=0 && flag[i]==false)
				{
					qu.push(i);

				}
			}
		}

	}

 

工程:https://github.com/lixuhui123/Graph

 

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值