views:

363

answers:

6

I need to implement a digraph(Directed graph) in c++ as part of a homework and i'm having some issues with how to represent the vertices and edges data types.
Can anybody please point me to a example or a simple c++ class that implements this so i can study it and extend from there?

I've googled for a bit but i only found results about using Boost or other libs, i just need something simple that doesn;t rely on any library.

Thank you.

A: 

This university paper might help you.

It's not the most complete, but it gives you an idea perhaps. I found it rather useful, it's also for a lecture so there is no risk of copying anything one shouldn't.

Skurmedel
A: 

I like to use Google's code search tool for examples. Have a look here: http://www.google.com/codesearch?hl=en&sa=N&q=digraph++lang:c%2B%2B&ct=rr&cs_r=lang:c%2B%2B

Greg
+1  A: 

Loosely, there are 2 straightforward ways of representing graphs:

  1. Connection Matrix
  2. List of Lists.

Each has advantages/disadvantages, depending on the application.

#2 will involve a lot of pointer fiddling.

#1 is often easier to use when doing graph transformationss.

In either one, you're going to have something like this:

template<typename T>
class node
{
   public:
   T data;
};

And the matrix and list of list classes will be pointing to dynamically allocated node's.

The implication is that you will have a graph class and a node class.

Paul Nathan
Connection matrix is only appropriate for dense graphs, and dense graphs are relatively uncommon. You really need to specify this. Typically the uses of dense and sparse representations are mutually exclusive, and there are all kinds of sparse representations which aren't anything like a list of lists.
Potatoswatter
-1: Also, a matrix shouldn't point to anything, it's more like a bitvector.
Potatoswatter
+4  A: 

There are two major ways of representing digraphs with data structures:

Node centric. This method represents each node as an object within your program, and each node contains information about other nodes it links to. The other nodes can be as simple as a list of nodes where there exists a directed edge between the current node and the target node.

Edge centric. This method represents each edge as an object within your program, and each edge contains information about which nodes it connects. In a digraph, each edge will have exactly one "source" and "destination" node (which may be the same node if you're considering self-loops). This method is essentially a list of ordered pairs.

Depending on the problem you're solving, one of these two basic forms will end up being most appropriate. More specific algorithms might need to add more information two the above basic structures, such as for example a list of all nodes reachable from the current node.

Greg Hewgill
This is a very good answer.
Paul Nathan
A: 

Try a vector< NodeType > with a multimap< NodeType *, EdgeType>.

multimap doesn't support subscripting [ x ] so you'll need to use edges.lower_bound() instead.

Alternatively, a map< pair< NodeType *, NodeType * >, EdgeType > can help look for an edge given two nodes. I used exactly that in one pretty heavy-duty program.

Here's an example for the first suggestion:

struct NodeType {
    int distance;
    NodeType( int d ) { distance = d; }
};
struct EdgeType  {
    int weight;
    NodeType *link;
    EdgeType( int w, NodeType *l ) { weight = w; link = l }
};

vector< NodeType > nodes;
nodes.reserve( 3 );
nodes.push_back( NodeType( 0 ) );
nodes.push_back( NodeType( 0 ) );
nodes.push_back( NodeType( 0 ) );

multimap< NodeType *, EdgeType > edges;
edges.insert( make_pair( &nodes[0], EdgeType( 4, &nodes[2] ) ) );
edges.insert( make_pair( &nodes[0], EdgeType( 1, &nodes[1] ) ) );
edges.insert( make_pair( &nodes[2], EdgeType( 2, &nodes[0] ) ) );

for ( multimap< NodeType *, EdgeType >::iterator iter = edges.lower_bound( &nodes[1] ),
  end = edges.upper_bound( &nodes[1] ); iter != end; ++ iter ) {
    cerr << "1 connects to " << iter->second.link - nodes.begin() << endl;
}
Potatoswatter
A: 
template<class T>
class node
{
public:
    T data;
    vector<node<T>*> edges;
}

You will most likely also want to store a list<node<dataType>*> of all the nodes.

BlueRaja - Danny Pflughoeft