Reputation: 23
I am a Python programmer trying to develop C++ proficiency. I have a silly question about vectors.
Suppose I have a vector like this
vector<int> adj;
Assume it contains some values. What does this operation do ?
adj[v].push_back(w)
Does it create vector of vectors ? How is it different from having a,
vector<vector<int>> adj
to begin with ?
Edit:: Associated code is a simple BFS on graph which compiles and runs perfectly.
class Graph
{
int V;
vector<int> *adj;
public:
Graph(int V);
void addEdge(int v, int w);
void BFS(int s);
};
Graph::Graph(int V)
{
this->V = V;
adj = new vector<int>[V];
}
void Graph::addEdge(int v, int w)
{
adj[v].push_back(w); // Add w to v’s list.
}
The BFS function is in GeeksForGeeks
Upvotes: 2
Views: 1869
Reputation: 310910
In the provided class definition there is no vector.
class Graph
{
int V;
list<int> *adj;
public:
Graph(int V);
void addEdge(int v, int w);
void BFS(int s);
};
There is declared a data member that has the type pointer to std::list<int>
.
In the constructor of the class
Graph::Graph(int V)
{
this->V = V;
adj = new list<int>[V];
}
there is allocated dynamically an array of objects of the type std::list<int>
and the address of the first element of the array is assigned to the data member adj
.
Thus in this statement
adj[v].push_back(w);
there is selected the element of the array with the index v
, adj[v]
, that represents an object of the type std::list<int>
and to this list is appended the object w
using the member function push_back
of the class template std::list
.
As for vectors then you indeed can declare a vector of vectors like
std::vector<std::vector<int>> v;
To use the subscript operator you have to create a required number of elements of the vector.
You can do it for example when the vector is declared.
std::vector<std::vector<int>> v( 10 );
This declaration declares a vector of vectors with 10 elements. Now you may use the subscript operator to add sub-vectors to the vector using the member function push_back
.
Here is a demonstrative program.
#include <iostream>
#include <vector>
int main()
{
std::vector<std::vector<int>> v( 10 );
for ( size_t i = 0; i < v.size(); i++ )
{
int value = 0;
for ( size_t j = 0; j < i + 1; j++ )
{
v[i]. push_back( value++ );
}
}
for ( const auto &sub_vec : v )
{
for ( const auto &item : sub_vec )
{
std::cout << item << ' ';
}
std::cout << '\n';
}
return 0;
}
Its output is
0
0 1
0 1 2
0 1 2 3
0 1 2 3 4
0 1 2 3 4 5
0 1 2 3 4 5 6
0 1 2 3 4 5 6 7
0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7 8 9
Upvotes: 1
Reputation: 13752
In the code that you present, adj
is created as a new list<int>[V]
. Which is not exactly what you ask about (i.e. it is not a vector, neither a list, it is a dynamically allocated array of lists).
Then:
adj[v].push_back(w)
Means: get the v
element in the array of lists (as v == index of the element to retrieve), it would be a list, then push_back
into this list w
.
Upvotes: 2
Reputation: 31447
The code you posted tries to call push_back
on a element of a vector
of int
s. That makes no sense since a int
is not an object with a push_back
member function. That code won't compile.
Upvotes: 1
Reputation: 5766
You have a 1-dimensional array. You can only add 1 element per index. What you are implying by adj[v].push_back(w)
is that you want to push element w at index v which is not possible since you declared the vector as
vector<int> adj;
To implement 2-d vector you need to define it as -
vector<vector<int> >adj;
On this your operation adj[v].push_back(w)
would work if v is a valid index.
Upvotes: 0
Reputation: 16670
Assuming vector<int> adj
:
adj[v].push_back(w)
will call the operator[]
on adj, which will return an int &
(assuming v
is some scalar). Then it will try to call push_back
on an int &
which will fail to compile.
Assuming vector<vector<int>> adj
:
adj[v].push_back(w)
will call the operator[]
on adj, which will return an vector<int> &
(assuming v
is some scalar). Then it will call push_back
on that vector<int> &
, appending the value w
to that particular vector.
Upvotes: 2