有人能解释我代码中for循环的差异吗?我知道迭代器是指向某些数据的指针,当我输入" * iter"我正在访问此指针指向的值(一个int)。但我不明白为什么汽车在这里不会以同样的方式工作。为什么我不需要在另一个for循环中取消引用顶点?
#include <iostream>
#include <list>
#include <queue>
class Graph {
public:
Graph(int num_v): num_vertices(num_v), adj_list(new std::list<int>[num_v]) {}
void add_edge(int u, int v) { adj_list[u].push_back(v); }
void bfs_traversal(int start) {
bool* visited = new bool[num_vertices];
for (int i = 0; i < num_vertices; i++)
visited[i] = false;
std::queue<int> q;
visited[start] = true;
q.push(start);
//std::list<int>::iterator iter;
while(! q.empty()) {
int node = q.front();
std::cout << node << " ";
q.pop();
/*
for (iter = adj_list[node].begin(); iter != adj_list[node].end(); ++iter) {
if (! visited[*iter]) {
visited[*iter] = true;
q.push(*iter);
}
*/
for (auto vertex : adj_list[node]) {
if (! visited[vertex]) {
visited[vertex] = true;
q.push(vertex);
}
}
}
}
private:
int num_vertices;
std::list<int>* adj_list;
};
int main()
{
Graph graph(4);
graph.add_edge(0,1);
graph.add_edge(0,2);
graph.add_edge(1,2);
graph.add_edge(2,0);
graph.add_edge(2,3);
graph.add_edge(3,3);
std::cout << "breadth first traversal starting from vertex 2\n";
graph.bfs_traversal(2);
return 0;
}
编译:g ++ -std = c ++ 11 来源:https://www.geeksforgeeks.org/breadth-first-traversal-for-a-graph/
答案 0 :(得分:5)
未注释的版本使用基于范围的 new InputStreamReader()
循环。
请注意,存在细微差别;与迭代器版本不同,for
是容器元素的值副本。出于这个原因,
vertex
使用较大的容器类型,甚至是for (const auto& vertex : adj_list[node]) {
时,是首选。
在引擎盖下,基于范围的表示法使用迭代器。因此,记住迭代器失效的C ++ 03规则仍然适用,这一点很重要。
答案 1 :(得分:5)
因为range-based for-loop为你做了。在这种特定情况下(假设c++11),需要生成与以下内容等效的代码(变量名仅用于展示):
{
auto && __range = adj_list[node];
for (auto __begin = __range.begin(), __end = __range.end();
__begin != __end; ++__begin) {
auto vertex = *__begin;
// ...
}
}
注意第5行,其中在解除引用迭代器之后进行复制。
正如@Bathsheba指出的那样,您可能需要const auto&
而非auto
。