图遍历问题
我的 Dijkstra 算法可以很好地找到路径。现在我想回去展示我走过的路。我标记一个访问过的顶点,并给它一个指向我来自“prev”的顶点的指针。不幸的是,当在 while 循环中循环时,这些指针会以某种方式被操纵,因此最后的顶点不知道它们来自哪里。你能帮助我吗?
可能这是我不明白的指针问题。我有一个复制构造函数和一个 = 运算符。
int MyMatrix::searchBreadth(MyVertex &from,MyVertex &to,int mode)
{
queue<MyVertex> q;//queue
vector<MyVertex> nb;//vector of neighbours
path=INFINITY;//path is very long
visits.push_back(from.getName());
from.setDistance(0);
MyVertex n("start");
from.setPrev(n);
q.push(from);
while(!q.empty())
{
MyVertex v=q.front();
q.pop();
int k=v.getDistance();
nb.clear();
nb = getNeighbours(v);
for(unsigned int i=0;i<nb.size();i++)
{
if((!nb[i].getPrev())&&path==INFINITY) nb[i].setPrev(v);
if(!mode){//unweighted
if(!wasVisited(nb[i].getName())){
nb[i].setDistance(k+1);
q.push(nb[i]);
}
}
if(mode){//length or weight
if(!wasVisited(nb[i].getName())){
int cost=0;
MyEdge e = m->getEdge(v,nb[i]);
if(mode==1)cost=(int) e.getLength();//length
if(mode==2)cost=(int) e.getWeight();//weigth
nb[i].setDistance(k+cost);
q.push(nb[i]);
}
}
if((nb[i].getName().compare(to.getName())==0) && (!wasVisited(nb[i].getName()))){//path found
int j=nb[i].getDistance();
if(j<path)path=j;
}
visits.push_back(nb[i].getName());
}//end of for
//end of 0size if
}//end of while
return path;
}
MyVertex::MyVertex()
{
name="null";
dist=0;
visited=false;
prev=0;
}
MyVertex::MyVertex(string name)
{
this->name=name;
visited=false;
dist=numeric_limits<int>::max();
prev=0;
}
MyVertex::~MyVertex(void)
{
if (!prev) prev=0;
}
MyVertex::MyVertex(const MyVertex& V){
this->name = V.name;
this->visited=V.visited;
this->dist=V.dist;
this->prev=V.prev;
}
MyVertex& MyVertex::operator=(const MyVertex& L){
if (this == &L){ return *this;
}else{
delete prev;
dist=L.dist;
name=L.name;
visited=L.visited;
prev=L.prev;
}
return *this;
}
My Dijkstra Algorithm works fine to find a path. Now I want to go back to show the way I went. I mark a visited vertex and give it a pointer to the vertex I came from "prev". Unfortunately these pointers get manipulated in some way when looping in the while loop, so that the vertices at the end don't know where they came from. Can you help me?
Probably it's a pointer problem I don't get. I have a copy constructor and a =operator.
int MyMatrix::searchBreadth(MyVertex &from,MyVertex &to,int mode)
{
queue<MyVertex> q;//queue
vector<MyVertex> nb;//vector of neighbours
path=INFINITY;//path is very long
visits.push_back(from.getName());
from.setDistance(0);
MyVertex n("start");
from.setPrev(n);
q.push(from);
while(!q.empty())
{
MyVertex v=q.front();
q.pop();
int k=v.getDistance();
nb.clear();
nb = getNeighbours(v);
for(unsigned int i=0;i<nb.size();i++)
{
if((!nb[i].getPrev())&&path==INFINITY) nb[i].setPrev(v);
if(!mode){//unweighted
if(!wasVisited(nb[i].getName())){
nb[i].setDistance(k+1);
q.push(nb[i]);
}
}
if(mode){//length or weight
if(!wasVisited(nb[i].getName())){
int cost=0;
MyEdge e = m->getEdge(v,nb[i]);
if(mode==1)cost=(int) e.getLength();//length
if(mode==2)cost=(int) e.getWeight();//weigth
nb[i].setDistance(k+cost);
q.push(nb[i]);
}
}
if((nb[i].getName().compare(to.getName())==0) && (!wasVisited(nb[i].getName()))){//path found
int j=nb[i].getDistance();
if(j<path)path=j;
}
visits.push_back(nb[i].getName());
}//end of for
//end of 0size if
}//end of while
return path;
}
MyVertex::MyVertex()
{
name="null";
dist=0;
visited=false;
prev=0;
}
MyVertex::MyVertex(string name)
{
this->name=name;
visited=false;
dist=numeric_limits<int>::max();
prev=0;
}
MyVertex::~MyVertex(void)
{
if (!prev) prev=0;
}
MyVertex::MyVertex(const MyVertex& V){
this->name = V.name;
this->visited=V.visited;
this->dist=V.dist;
this->prev=V.prev;
}
MyVertex& MyVertex::operator=(const MyVertex& L){
if (this == &L){ return *this;
}else{
delete prev;
dist=L.dist;
name=L.name;
visited=L.visited;
prev=L.prev;
}
return *this;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您遗漏了很多代码,但您似乎正在调整节点的
Distance
- 并设置其prev
- 而没有首先检查它是否已经有较小的距离
。一旦找到任何路径,就停止设置prev
,这样如果以后找到更短的路径,其节点可能不会被标记。You're leaving a lot of code out, but you seem to be adjusting the
Distance
of a node -- and setting itsprev
-- without first checking whether it already has a lesserDistance
. And once you've found any path, you stop settingprev
, so that if you later find a shorter path, its nodes may not be marked.