kruskal implement in c adjacency list or adjacency matrix - c

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.

Related

How to make an array of arrays in C?

Is it possible to make an array of arrays in C?
More specifically, is it possible to make a list (array) of adjacency lists (arrays)?
And if so, how?
My textbook uses a list of adjacency lists for Dijkstra's algorithm (and in a lot of other algorithms) instead of using an adjacency matrix, though the book is in pseudocode and even then it makes no reference whatsoever on how to implement the list...
Supposedly, list of adjacency lists are more efficient in a lot of algorithms than adjacency matrices. I thought of using linked lists, but AFAIK it would be the same as using an adjacency matrix, so it would make no point at all to implement it this way...
Did you mean a multidimensional array?
int mdarr[10][20];
Is it possible to make an array of arrays in C?
Yes.
More specifically, is it possible to make a list (array) of adjacency
lists (arrays)?
Yes, it can be implemented using a linked list (or array in your case) of linked lists.
And if so, how?
One list (or array) could maintain nodes, each of which will point to the actual adjacency list as well as contain information about the current point of the graph. This can be implemented creating a struct with the relevant data (one information field and one next pointer, and one pointer to adjacency list)
The second list will be the actual adjacency list of each node. It will be pointed to by the corresponding nodes of the first list. It will contain nodes, each of which will be a graph point connected to the corresponding point in the initial list. It can be implemented similarly, by creating a struct having the relevant data (one field for the next pointer, and one information field).
This is not a multi-dimensional array but is completely different. This will use less space than an adjacency matrix, if your graph is sparse.
As an example, lets take A, B, C, D to be the nodes of an undirected graph such that A is connected to B and C.
Then the lists will be like this :
A -> B -> C -> D
| | |
B A A
|
C
Did you mean a three-dimensional array?.
Yo define an adjacency matrix like this aMat[3][3] (graph of three elements).
So, you could define, for example 4 graphs of three elements each like this: aMatMulti[4][3][3].

Ideas for data structure for implementing graph in c

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.

C programming language Graph Structure

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.

Graph Implementation in C

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)

How to search a specific node in a graph structure in C?

Not that I have time to discuss this properly to reach a conclusion and adapt my code because the phase one (of three) of a school project is in 24hrs, but at least I need to know if I did the correct decision.
I'm using linked lists and here's my structures:
typedef struct sCity {
int cityID;
char *cityName;
struct sCityLink *links;
struct sCity *next;
} nCity, *City;
typedef struct sCityLink {
City cityLinkParent;
City cityLinkTo;
struct sCityLink *next;
} nCityLink, *CityLink;
Basically, I have lots of cities and those cities are linked all together, like a graph. For instance, A, B, C, D and E they are inserted in this order into the structure City. Then, I connect A to B, C and D, B to C, D, E, C to D and E and D to E.
Now, let's say I need to go to city E. This is the last one in the linked list and it takes time to traverse the linked list all the way. Maybe not on this example with 5 cities but in the real app I'm supposed to support like 10,000 cities at least. But the shortest route is from A (which is the starting point) from C to E (or it could be A-D-E or A-B-E, doesn't matter).
Do my structures allow me to find the shortest route from A to E without traversing the whole linked list one by one? If not, what I'm doing wrong?
If yes, how can I do that? I don't have a clue how can I find such a path...
There are two separate issues - one, you probably want to find a City pointer for a city ID (eg. "E"). You cannot do that in less than linear time with your structures; if you need it faster, use a hashtable or binary search tree.
Two, you want to find a path between two given cities. For this you'd probably use the BFS algorithm, for which your data structure is just fine. Note that BFS takes O(V+E) time where V and E are the vertex and edge count of the induced subgraph whose vertices' distance from the start vertex is not greater than the distance from start to end vertex. Which means in the worst case, it takes more time than traversing the list of cities.
You can use an algorithm called Breadth-First Search (BFS). You need to implement a "color" flag on each node to use it. Note that this algorithm only works if your edges are unweighted -- if 2 cities are connected, then they are of equal distance.
If the edges have weight (which it does not look like they do), you need something like Dijkstra's Algorithm or A*.

Resources