Graph incidence list implementation

Armand A picture Armand A · Oct 11, 2010 · Viewed 8.6k times · Source

I'm considering graph data structure implementations and am looking at the "incidence list" representation. There is a brief description of it here:

Incidence list

So each vertex in the graph stores a list of those edges upon which it is incident.

Given that my graph is a directed graph, I'm not very clear from this description on a couple of points:

  1. Does the graph itself also store a list of all edges?
  2. Do vertices only store outgoing edges, or incoming and outgoing?
  3. If both, are they in separate lists?

I'm quite familiar with the other graph representations (adjacency list, adjacency matrix, edge list, incidence matrix), so this isn't a question about graph implementations in general, just this particular one.

Any pointers would be much appreciated.

Answer

JBirch picture JBirch · Dec 20, 2010

I know I'm perhaps raising an old question from the dead, but I felt it appropriate to comment.

You can make an incidence list graph structure, and you can also tweak it for digraphs.

Consider a LinkedList<Vertex> object and a LinkedList<Edge> object. This would let you iterate over all edges and all vertices, but contains no information about how everything is connected.

Say we add, then, several LinkedList<Connection> objects. In fact, one for each Vertex. A Connection is simply where an Edge and a Vertex Meet. Thus an Edge will have two Connection objects (For an undirected graph), and a Vertex will have one LinkedList<Connection> object, representing connections to every Edge that is connected to it. This is, in essence, an incidence list.

You can modify this to represent a digraph if you delete some of those Connection objects. More specifically, you'll have to choose where to not have those references. You might choose to delete a Connectionfrom the associated LinkedList<Connection> if you don't want to be able to see an Edge from a Vertex (for the example above, N2 would have an empty LinkedList<Connection>). You might instead choose to make the references optional on the Edge(For the example above, E1 would have one Connection pointing at N2 and one Connection null, allowing traversal from E1 to N2, but not back onto N1. Your choice of how to implement this would be entirely up to you. One is more intuitive - Edges are directed, so removing the connections on Edges to dictate which way they go seems logical. The other might seem a bit more complex at first, but will stop you needlessly hopping onto edges that lead nowhere when doing breadth first and depth first searches.

In point form:

  1. In my implementations of a incidence list, I have. Do you need to for your implementation?

  2. Strictly speaking, you could get by storing only outgoing edges. However, backtracking algorithms might benefit from being able to backtrack along references they traveled. You can implement around this, of course, with some sort of history, so it's probably not much of a consideration.

  3. If you do both, you would probably need some way to differentiate whether it's incoming or outgoing. Whether that's by having two LinkedList<Connection> objects on the Vertex, or by having a boolean pointingToVertex primitive on Connection, or whatever. Maybe your Edge would be directed, and undirected edges would be made of two edges pointing opposite ways. Considerations to be made depending on the needs of your structure.