patterncppMinor
BFT/DFT/Topological graph implementation
Viewed 0 times
graphdftbfttopologicalimplementation
Problem
I am trying to learn graphs and implement in code. Can you please review my code and give me feedback?
Source code
Class Edge
Class Vertex
Class Graph
```
class Graph
{
private:
typedef std::map VertexMap;
typedef std::map::iterator VertexIterator;
typedef std::map::const_iterator VertexConstIterator;
bool visit(int v, std::list & sortedList);
VertexMap vertices;
public:
void addVertex(int v);
void addEdge(int v1, int v2);
void print();
void BreadthFirstTour(int v);
void DepthFirstTour(int v);
void TopologicalSort();
void resetStates();
};
void Graph::addVertex(int v)
{
vertices.insert( std::make_pair(v, Vertex(v)) );
}
void Graph::addEdge(int v1, int v2)
{
VertexIterator iter = vertices.find(v1);
if (iter != vertices.end())
{
Edge edge(v2);
iter->second.adjList.push_back(edge);
}
iter = vertices.find(v2);
iter->second.indegree++;
}
void Graph::print()
{
VertexConstIterator iter = vertices.begin();
for (; iter != vertices.end(); ++iter)
{
cout second q;
VertexConstIterator iter = vertices.find(v);
if (iter != vertices.end())
{
q.push(iter->first);
}
else
{
cout ::const_iterator iter = v.adjList.begin();
while (iter != v.adjList.end())
{
//cout dest dest);
if (citer
Source code
#include
using namespace std;
#include
#include
#include Class Edge
class Edge
{
public:
int dest;
int weight;
Edge(int dest) : dest(dest), weight(0) {}
};Class Vertex
class Vertex
{
public:
int orig;
std::list adjList;
bool visited;
int indegree;
Vertex() : orig(-1), visited(false), indegree(0) {}
Vertex(int v) : orig(v), visited(false), indegree(0) {}
friend bool operator==(const Vertex & v, int data);
friend std::ostream & operator::const_iterator iter = v.adjList.begin();
for(; iter != v.adjList.end(); ++iter)
{
os dest;
}
return os;
}Class Graph
```
class Graph
{
private:
typedef std::map VertexMap;
typedef std::map::iterator VertexIterator;
typedef std::map::const_iterator VertexConstIterator;
bool visit(int v, std::list & sortedList);
VertexMap vertices;
public:
void addVertex(int v);
void addEdge(int v1, int v2);
void print();
void BreadthFirstTour(int v);
void DepthFirstTour(int v);
void TopologicalSort();
void resetStates();
};
void Graph::addVertex(int v)
{
vertices.insert( std::make_pair(v, Vertex(v)) );
}
void Graph::addEdge(int v1, int v2)
{
VertexIterator iter = vertices.find(v1);
if (iter != vertices.end())
{
Edge edge(v2);
iter->second.adjList.push_back(edge);
}
iter = vertices.find(v2);
iter->second.indegree++;
}
void Graph::print()
{
VertexConstIterator iter = vertices.begin();
for (; iter != vertices.end(); ++iter)
{
cout second q;
VertexConstIterator iter = vertices.find(v);
if (iter != vertices.end())
{
q.push(iter->first);
}
else
{
cout ::const_iterator iter = v.adjList.begin();
while (iter != v.adjList.end())
{
//cout dest dest);
if (citer
Solution
Don't put using namespace std
before including other header files
If you must do it then put it after all the includes. But preferably don't use it at all.
Do you really want all the members of Vertix to be public?
Equality test is correct:
But it is easier to read when written like this:
When you have an operator > (in the long run you probably will). Thus when writing your output stream you want to write it in a way that makes reading it back in easy. So when you class contains things like vectors it is useful to prefix them with a count of elements (not a termination marker). Also any sub elements should be printed with their own stream operator << so you should probably write one for Edge as well.
Typedef the iterators in terms of the container. That way if you change the container you only need to make one change (not a cascade of changes).
could be written as:
Here is where you public members are going to haunt you.
You are binding your representation of a vertices to always contain its list of edges in this manor. You should really define a more abstract interface on the class that will allow you to change the internal representations without affecting the implementation of Graph.
When you add edges to a graph.
You check that the source is there. But you do not check that a destination node has been created. I would expect this to be more symmetrical.
Is the method 'void resetStates()' really a member of the public interface?
In your BreadthFirstTour/DepthFirstTour traversal of the graph. Its not really a breadth first/Depth first tour (as this implies a breadth or depth) while a graph is bit less symmetric than that (especially since edges have a weight and the graph may not be fully connected).
But as part of the implementation you actually store whether a node (vertex) has been visited as a member of the vertex. You are basically tightly coupling the traversal of the graph to its implementation which may restrict you in future enhancements to the graph (and limiting how the graph can be traversed).
You can de-couple how the graph is traversed from the implementation of the graph by using a visitor pattern. This also conforms to the open/closed principle by making your class open to expansion but closed to change by allowing the traversal mechanism to be specified externally to the graph.
before including other header files
If you must do it then put it after all the includes. But preferably don't use it at all.
#include
using namespace std;
#include
#include
#include Do you really want all the members of Vertix to be public?
public:
int orig;
std::list adjList;
bool visited;
int indegree;Equality test is correct:
if (v.orig == data) return true;
return false;But it is easier to read when written like this:
return v.orig == data;When you have an operator > (in the long run you probably will). Thus when writing your output stream you want to write it in a way that makes reading it back in easy. So when you class contains things like vectors it is useful to prefix them with a count of elements (not a termination marker). Also any sub elements should be printed with their own stream operator << so you should probably write one for Edge as well.
Typedef the iterators in terms of the container. That way if you change the container you only need to make one change (not a cascade of changes).
typedef std::map VertexMap;
typedef std::map::iterator VertexIterator;
typedef std::map::const_iterator VertexConstIterator;could be written as:
typedef std::map VertexMap;
typedef VertexMap::iterator VertexIterator;
typedef VertexMap::const_iterator VertexConstIterator;
// ^^^^^^^^^ Use the container type we just defined.Here is where you public members are going to haunt you.
iter->second.adjList.push_back(edge);You are binding your representation of a vertices to always contain its list of edges in this manor. You should really define a more abstract interface on the class that will allow you to change the internal representations without affecting the implementation of Graph.
When you add edges to a graph.
You check that the source is there. But you do not check that a destination node has been created. I would expect this to be more symmetrical.
Is the method 'void resetStates()' really a member of the public interface?
In your BreadthFirstTour/DepthFirstTour traversal of the graph. Its not really a breadth first/Depth first tour (as this implies a breadth or depth) while a graph is bit less symmetric than that (especially since edges have a weight and the graph may not be fully connected).
But as part of the implementation you actually store whether a node (vertex) has been visited as a member of the vertex. You are basically tightly coupling the traversal of the graph to its implementation which may restrict you in future enhancements to the graph (and limiting how the graph can be traversed).
You can de-couple how the graph is traversed from the implementation of the graph by using a visitor pattern. This also conforms to the open/closed principle by making your class open to expansion but closed to change by allowing the traversal mechanism to be specified externally to the graph.
Code Snippets
#include <iostream>
using namespace std;
#include <list>
#include <queue>
#include <map>public:
int orig;
std::list<Edge> adjList;
bool visited;
int indegree;if (v.orig == data) return true;
return false;return v.orig == data;typedef std::map<int, Vertex> VertexMap;
typedef std::map<int, Vertex>::iterator VertexIterator;
typedef std::map<int, Vertex>::const_iterator VertexConstIterator;Context
StackExchange Code Review Q#4561, answer score: 2
Revisions (0)
No revisions yet.