我遇到了队列问题。对图形建模,我正在用C ++做一个最短路径算法。
在我的while (!q.empty())
中,当我返回此声明时,前面vertex*
会被更改。
你能弄明白为什么吗?
int MyMatrix::searchBreadth(MyVertex* from,MyVertex* to)
{
queue<MyVertex*> q;
path=INFINITY;
from->visit();
from->setDistance(0);
q.push(from);
//here q.front()'s attributes get changed when returning from the for-loop
while(!q.empty())
{
MyVertex* v=q.front();
q.pop();
int k=v->getDistance();
vector<MyVertex> nb=getNeighbours(*v);
for(int i=0;i<nb.size();i++)
{
if(nb[i].getDistance()==INFINITY)
{
nb[i].setDistance(k+1);
q.push(&nb[i]);
}
if((nb[i].getName().compare(to->getName())==0)
&& !nb[i].isVisited())
{
//path found
int j=nb[i].getDistance();
if(j<path) path=j;
}
nb[i].visit();
}
}
return path;
}
这里是getNeighbours()
vector<MyVertex> MyMatrix::getNeighbours(MyVertex &v)
{
int index=0;
for(int l=0; l<stations.size(); l++ )
{
if(stations[l].getName().compare(v.getName())==0)index=l;
}
vector<MyVertex> out;
for(int k=0;k<matrixSize;k++)
{
if(matrix[index][k].getName().compare("null")!=0)
{
out.push_back(matrix[index][k].getTo());
}
}
return out;
}
答案 0 :(得分:3)
您的问题很微妙,但与q.push(&nb[i])
有关。你正在做的是添加一个指向向量中某个位置的指针,这在概念上与添加指向MyVertex
对象的指针不同。邻居向量包含“按值”MyVertex
个对象(如果这有助于您理解问题)。
在内存中查看nb
可能有所帮助:
0 1 I
nb [MyVertex0|MyVertex1| ... |MyVertexI]
+---------+
| (Notice it is NOT pointing to MyVertex1!)
&nb[1]------------+
当您按&nb[1]
时,您正在推送地址nb + (1 * sizeof(MyVertex))
。在堆栈上声明nb
,因此该地址将位于堆栈的某个位置。
因此,当您的for
循环返回时,nb
会被刷新(可以这么说)并添加新数据。但是,您的队列q
包含nb
中不再有效的地址!
简单地说:您的队列引用了向量中的LOCATION,而不是向量中的DATA 。
如果你想保持你的方法不变,这意味着 getNeighbors
需要改变以返回MyVertex*
的向量。
您只需编辑BreadthFirstSearch
即可获得两个MyVertex&
,而不是指针。然后,您可以将q
更改为queue<MyVertex>
,v
更改为MyVertex
,最后您应将q.push(&nb[i])
更改为q.push(nb[i])
。