17

I keep seeing everywhere that there are 3 ways to represent graphs:

  1. Objects and pointers
  2. Adjacency matrix
  3. Adjacency lists

However, I just plain don't understand what these Object and pointer representations are - yet every recruiter, and many blogs cite Steve Yegge's blog that they are indeed a separate representation.

This widely accepted answer to a very similar question seems to suggest that the vertex structures themselves have no internal pointers to other vertices, and instead all edges are represented by edge structures which contain pointers to the adjacent vertices.

How does this representation offer any discernible analytical advantage in any scenario?

Community
  • 1
  • 1
Kat
  • 473
  • 5
  • 17

4 Answers4

1

From the top of my head, I hope I have the facts correct.

Conceptually, graph tries to represent how a set of nodes (or vertices) are related (connected) to each other (via edges). However, in actual physical device (memory), we have a continuous array of memory cell.

So, in order to represent the graph, we can choose to use a matrix. In this case, we use the vertex index as the row and column and the entry has value 1 if the vertices are adjacent to each other, 0 otherwise.

Alternatively, you can also represent a graph by allocating an object to represent the node/vertex which points to a list of all the nodes that are adjacent to it.

The matrix representation gives the advantage when the graph is dense, meaning when most of the nodes/vertices are connected to each other. This is because in such cases, by using the entry of matrix, it saves us from having to allocate an extra pointer (which need a word size memory) for each connection.

For sparse graph, the list approach is better because you don't need to account for the 0 entries when there is no connection between the vertices.

Hope it helps.

xyz
  • 870
  • 2
  • 8
  • 16
  • 5
    Yes, these are correct concerning adj matrix and adj list representations; however the question specifically asks about the object and pointers representation where the only place information about edges are stored in edge objects themselves. – Kat Jan 07 '15 at 02:12
  • Ah...I see what you mean. My apology for misinterpreting your original question. Then I think an earlier similar is here: http://stackoverflow.com/questions/3287003/three-ways-to-store-a-graph-in-memory-advantages-and-disadvantages – xyz Jan 07 '15 at 02:29
  • Again just from top of my head, I'm guessing that object and pointer would have an advantage against adj list when a large search is concerned, since it doesn't need to load another separate "head of list" when traverse from neighbor to neighbor. But adj list would be more useful if you need to quickly answer questions like "which nodes are the direct neighbor of the current node?". – xyz Jan 07 '15 at 02:36
  • the accepted answers to that question don't actually answer the question - like everything else, it just points on the obvious pros/cons of adj.mat vs adj.list. Object and pointer does not help with large search. The ONLY place I can think it may be beneficial to have explicit edge objects is for Kruskal's algorithm – Kat Jan 07 '15 at 03:28
1

Objects and pointers representation reduces space complexity to exactly V+E, where V is the number of vertices, E - the number of edges (down from V+2E in Adjacency List or even 2V+2E if you store index->Vertex mapping in a separate hash map), sacrificing time complexity: particular edge lookup will take O(E), which equals O(V^2) in a Dense graph (up from O(V) in Adjacency List). The space saving is achieved by removing duplicated edges that appear in the Adjacency List.

Serge Mosin
  • 397
  • 1
  • 6
  • 15
0

For now I have a hard time finding a pro w.r.t typical "graph algorithms". But it sure is possible to represent a graph with objects and pointers and a very natural thing to do if you think of it as a representation of something you just drew on a whiteboard.

Think of a scenario where you want to combine nodes of a graph in a certain order. Nodes have payloads that contain domain data, the graph structure itself is not a core aspect of your program.

Sure, you can update your lists / matrix for every operation, but given an "objects and pointers" structure, you can do the merging locally. Further, if nodes have payloads, it means that lists/matrix will feature node id's that identify the actual node objects. A combination would mean you update your graph representation, follow the node identifiers and do the actual processing. It may feel more intuitively to work on your actual node objects and simply remove pointerswhen collapsing a neighbor (and delete that node) .

Besides, there are more ways to represent a graph:

  • E.g. just as triples, like Turle does
  • Or as offset representation (offsets per node into an edge array), e.g. this Boost data structure (disclaimer: I have not tested the linked implementation myself)
  • etc
b.buchhold
  • 3,837
  • 2
  • 24
  • 33
0

Here a way i have been using to create Graph with this concept :

#include <vector>

class Node
{
    public:
        Node();
        void setLink(Node *n); // *n as argument to pass the address of the node
        virtual ~Node(void);
    private:
        vector<Node*> m_links;
};

And the function responsible for creating the link between vertices is :

void Node::setLink(Node *n)
{
    m_links.push_back(n);
}