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

发布了157 篇原创文章 · 获赞 98 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_43447989/article/details/104214773
今日推荐