I have been playing around with an adjacency list implementation of a graph class, on which I'd like to be able to run a build and test several graph algorithms. The code I have below works and I have been able to implement BFS, DFS, Dijkstra and Prim's algorithms, but I'm not very satisfied with it and would very much appreciate criticism.
One of the key problems that I can see is that the neighbours of a node
are private and therefore to traverse them inside a function (i.e. Dijkstra) I need to make this function a friend
of the node
class. I suspect that I should implement smart pointers to solve this but before I do this I'd like to consider other suggestions (maybe custom iterators?).
I also think there is a problem with how the nodes are being initialised, as I would prefer not having to call setKey
in the graph::addNode
function.
The node class:
class node{
public:
node() {}
node(int k) : key(k){}
void addNeighbour(int k, int weight = 1){
if (this->key == k) return;
neighbours.push_back(std::make_pair(k,weight));
}
inline int getKey() const {return key;}
inline void setKey(const int k){key = k;}
void display() const{
for (std::list<std::pair<int,int> >::const_iterator it = neighbours.begin(); it != neighbours.end(); ++it){
std::pair<int,int> entry = *it;
std::cout << entry.first << " ";
}
std::cout << std::endl;
}
friend void bfs(graph &g, int src);
friend graph prim(graph &g);
friend void dijkstra(graph &lg, int src);
private:
std::list<std::pair<int, int> > neighbours; //first element in pair corresponds to vertex key, second to the edge weight between them
int key;
};
The graph class:
class graph{
public:
graph(const int sz) : size(sz),
nodes(sz, node()),
directed(false) {}
void addNode(int key, const std::vector<std::pair<int,int> > &input);
void display() const;
node &operator[](const int i){return nodes[i];}
inline int getSize() const {return size;}
private:
std::vector<node> nodes;
int size;
bool directed;
};
void graph::addNode(const int key, const std::vector<std::pair<int,int> > &input){
nodes[key].setKey(key);
for (std::vector<std::pair<int,int> >::const_iterator it = input.begin(); it != input.end(); ++it){
std::pair<int,int> entry = *it;
nodes[key].addNeighbour(entry.first, entry.second);
if (!directed){
nodes[entry.first].addNeighbour(key, entry.second);
}
}
}