I want to know what is best and fastest way of implementing graph data structure and its related algorithms.
Adjacency-List is suggested by the book.
But I fail to understand for a large graph when I want to find the edge between the two vertices v1 and v2
I will have to traverse through the array which will be O(n).
Is my understanding correct or there is better approach to get this done.
first of all, it is not O(n). Keep the lists sorted and it will be O(logN). Adjacency list need not be necessarily implemented by a linked list. It's more usual to have an array.
Another very popular approach is the adjacency matrix nxn where a[i][j] is 1 (or the weight of the edge) if i and j are connected and 0 otherwise. This approach is optimal for dense graphs, which has many edges. For sparse graphs the adjacencly list tends to be better
You can use an adjacency matrix instead of the list. It will let you find edges very quickly, but it will take up a lot of memory for a large graph.
There are many ways of implementing graphs. You should choose the one that suits your algorithm best. Some ideas:
a) Global node and edge list.
b) Global node list, per-node edge list.
c) Adjacency matrix (A[i][j] = w(edge connecting Vi-Vj if it exists), 0 otherwise)
d) Edge matrix.(A[i][j] = 1 if the Ei connects the node Vj)
Related
I want to implement two dimensional grid graph in C. Is it better to start with a single node and continue adding nodes when it is required or forming it one at a time? Code snippet would be great.
First of all StackOverflow community doesn't like to give whole solutions to given problems. It's always better to propose something on your own and show that you thought the problem over. Your problem statement is not specific. Do you know the number of vertices at compile time? If so the simple two-dimensional array would be enough:
int connections[100][100];
If not but the number of vertices is constant maybe you should consider using dynamic allocation:
int** connections = malloc(sizeof(int*)*numberOfVertices);
for (int i = 0; i < numberOfVertices; i++) {
connections[i] = malloc(sizeof(int)*numberOfVertices);
}
This two solutions of course cause some problems. They for example are very memory expensive (especially when the graph is sparse). This is why you always can use some dedicated struct.
If you are thinking of adding nodes as you go, then you should use an adjacency list (a linked list of linked lists) to represent your graph; especially since adding as you go means you don't know whether your graph will be parse. But if you already know the size of your graph, then use a square array (n by n, where n is number of nodes).
I want to implement a graph in C. I am confused on how should I store each node. I was first thinking of using a linked list but how can I store the next nodes connected to one node.
Any ideas what data structure should I use and how should I use it?
There are some well known ways to do that.
One is to use a bidimensional array of size [n][n] where n is the number of nodes. And then set graph[a][b]= 1 if there is a link from a to b. This method is in general fast but uses a lot of memory, expecially if there are not so many links and many nodes.
Another way is to make a list (or an array, for the matter) of all nodes and set the content of everyone of them to point to a dynamic array or to a list of nodes it is linked to.
The data structure that is helpful in case your graph is sparse is an adjacency list(linked list of linked lists) that is when you have few connections(edges) between the vertices.
If your graph is dense then use an adjacency matrix(nxn) 2 dimensional array that is the case your vertices have lots of edges between them.
I am reading the textbook Introduction to Algorithms aka CLRS, I want to implement the mst using kruskal algorithm in c, what I want to know is, which graph implementation should I use, the adjacency list or adjacency matrix? I think it is not intuitive to sort the edges when using the adjacency list, the represent of edge in adjacency list is confusing when define the adjacency list like this:
typedef struct tagAdjList
{
int endPointIndex;
struct tagAdjList * next;
}AdjNode, *AdjList, *AdjPNode;
when sorting the edges, I want to using an array of pointers to pointing to the nodes defined above, the question is the struct defined above can't find the start point of the edge but the end point. So I changed the struct like this:
typedef struct tagAdjList
{
int startPointIndex;
int endPointIndex;
struct tagAdjList * next;
}AdjNode, *AdjList, *AdjPNode;
what I want to ask is: is OK to define the adjancency list like this? or there are better practice? or I just should use the adjacency matrix(since I saw some people implement the kruskal using the matrix when searching the Internet)? why?
Sorry for the poor English. any help will be appreciated.
For the purposes of implementing Kruskal's algorithm it does not matter in what way you represent your graph, because you never sort edges that belong to a vertex. Rather, you put all edges into a single array, and then sort that array in ascending order.
The representation of your graph does not matter, as long as you can walk it, and collect all edges into a single array (first, you walk the graph to count the edges, then allocate an array of sufficient capacity, and finally you walk the graph again, putting pointers to the edges into the dynamically allocated array).
Once the pointers to your edges are in an array, sort the array (for example, with qsort) and run Kruskal's algorithm. You will need to implement Disjoint Sets in order to merge forests efficiently; as long as you have no trouble implementing linked lists, implementing disjoint sets should give you absolutely no trouble.
The first structure you mention is the standard representation of (sparse) graphs. Note that you will need a weight field as well. I would keep this as the permanent representation of the graph, as long as it is sparse at least.
Yes, for Kruskal's you'll need a structure more like the latter as you need an explicit source vertex. I would define a different structure that doesn't have the linked list just for Kruskal's:
int startPointIndex;
int endPointIndex;
int weight;
You'll allocate an array of those structures, fill them in with the edges from the graph, sort them by weight, then scan through them doing disjoint set unions of the endpoints.
Most articles about Dijkstra algorithm only focus on which data structure should be used to perform the "relaxing" of nodes.
I'm going to use a min-heap which runs on O(m log(n)) I believe.
My real question is what data structure should I used to store the adjacent nodes of each node?
I'm thinking about using an adjacency list because I can find all adjacent nodes on u in O(deg(u)), is this the fastest method?
How will that change the running time of the algorithm?
For the algorithm itself, I think you should aim for compact representation of the graph. If it has a lot of links per node, a matrix may be best, but usually an adjacency list will take less space, and therefore less cache misses.
It may be worth looking at how you are building the graph, and any other operations you do on it.
With Dijkstra's algorithm you just loop through the list of neighbours of a node once, so a simple array or linked list storing the adjacent nodes (or simply their indices in a global list) at each node (as in an adjacency list) would be sufficient.
How will that change the running time of the algorithm? - in comparison to what? I'm pretty sure the algorithm complexity assumes an adjacency list implementation. The running time is O(edges + vertices * log(vertices)).
I have some trouble with building Graph Structure. I know how to build a simply linked list and doubly too. But I want to construct a graph structure like in this site (the pic. output) http://www.cs.sunysb.edu/~algorith/files/graph-data-structures.shtml
You have three common solutions:
an adjacency matrix (in which you store a matrix of N*N where N is the number of vertices and in matrix[x][y] you will store a value if x has an edge to y, 0 otherwise
an edge list, in which you just keep a long lists of edges so that if the couple (x,y) is in the list, then there is an edge from x to y
an adjacency list, in which you have a list of vertices and every vertex x has a list of edges to the nodes for which x has an edge to.
Every different approach is good or bad according to
space required
computational complexity related to specific operations more than other
So according to what you need to do with the graph you could choose any of those. If you want to know specific characteristic of the above possible implementations take a look at my answer to another SO question.