广度优先遍历
---一石激起千层浪
和深度优先遍历一样,广度优先遍历也是一种常用的搜索算法,它并没有固定的代码格式,只是一种遍历方式的思想。广度优先遍历一般用于求最短路径问题,我们用一个社交图来举例。
上图是一个无向图,用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);
}
}
}
}