如何解决如何使用stl迭代器和队列来实现图形的广度优先遍历?
在概念上理解BFS的同时,我还没有掌握如何使用迭代器和队列来实现BFS。如果有人可以给我一些见解,以了解如何在我的代码中正确使用迭代器,我将非常感激。谢谢。
我什至在这里不确定迭代器是否是个好主意,我也尝试学习自动类型,但是我不确定如何使用它。
#ifndef GRAPH_H
#define GRAPH_H
#include<vector>
#include<iostream>
using namespace std;
struct vertex;
struct adjVertex{
vertex *v;
};
struct vertex{
string name;
bool visited = false;
int distance = 0;
vector<adjVertex> adj;
};
class Graph
{
public:
void addEdge(string v1,string v2);
void addVertex(string name);
void displayEdges();
void breadthFirstTraverse(string sourceVertex);
int getConnectedBuildings();
private:
vector<vertex*> vertices;
};
#endif // GRAPH_H
void Graph::breadthFirstTraverse(string sourceVertex){
//first initialize everything as not found
for(int i = 0; i < vertices.size(); i++)
{
vertices[i]->visited = false;
}
//pointer to sourceVertex
vertex *vstart;
for(int i=0; i < vertices.size(); i++)
{
if(vertices[i]->name == sourceVertex){
vstart = vertices[i];
cout << "Starting vertex (root): " << vstart->name << " -> " << endl;
}
}
queue<vertex*> q;
vstart->visited = true;
q.push(vstart);
vertex *n;
vector<int>:: iterator i;
while(!q.empty()){
n = q.front();
q.pop();
for(i = n->adj.begin(); i != n->adj.end(); ++i){ // error: no viable overloaded '='
cout << n->adj[*i].v->name <<"(" << n->adj[*i].v->distance << ")" << " ";
if(!n->adj[*i].v->visited){
n->adj[*i].v->visited = true;
q.push(*i); //no matching member function for call to 'push'
}
}
}
}
解决方法
您的第一个错误消息:
错误:没有可行的重载'='
这与以下内容有关:
vector<int>:: iterator i;
for(i = n->adj.begin(); i != n->adj.end(); ++i) {
请注意,n->adj.begin()
的类型为vector<adjVertex>::iterator
。但是,变量i
的类型为vector<int>::iterator
。编译器错误将比您显示的错误多得多。这本来可以很好地解释问题。
这应该纠正错误:
for(vector<adjVertex>::iterator i = n->adj.begin(); i != n->adj.end(); ++i) {
自从您询问auto
以来,这也是可以接受的:
for(auto i = n->adj.begin(); i != n->adj.end(); ++i) {
在这种情况下,i
的类型将为vector<adjVertex>::iterator
。
第二个错误与之相关:
没有匹配的成员函数可调用“ push”
为此:
q.push(*i);
在这里,q
的类型为queue<vertex*>
,而*i
的类型为int
。如果应用我的上述修复程序,则*i
的类型将为adjVertex
,这将产生相同的问题。因此,您需要:
q.push(i->v);
回到第一个错误,有一种更现代的迭代方法(自C ++ 11起),使用基于范围的循环 :
for (auto& elem : n->adj) {
上面,它将遍历您的adj
向量,使您可以通过值为elem
的值adjVertex&
访问其元素。因此,您可以使用vertex*
访问该元素中的elem.v
。
我对我的代码做了些微改动以解决它。我没有使用迭代器(for循环中的int变量很好),而且我不需要像这样取消引用
n->adj[*i].v->name
这才是最终成功的
void getConnectedComponents(string buildingName,vertex *& node){
//pointer to sourceVertex
vertex *vStart;
vStart = node;
queue<vertex*> q;
vStart->visited = true;
q.push(vStart);
vertex *n; //pointer to elements in queue
while(!q.empty()){
n = q.front();
q.pop();
for(int i = 0; i < n->adj.size(); i++){
if(!n->adj[i].v->visited){
//cout << n->adj[i].v->name <<"(" << n->adj[i].v->distance << ")" << " ";
n->adj[i].v->visited = true;
q.push(n->adj[i].v);
}
}
}
cout << endl;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。