how to program Prim's and Kruskal's algorithm using adjacency lists in C - data-structures

I have understood and implemented Prim's and Kruskal's algorithm using adjacency matrix but I am not understanding how to write a program using adjacency lists
I tried creating 2 matrices one for min weight for each edge and which is a two dimensional matrix and another matrix for the visited edges. But I couldn't proceed with that approach. Please provide an approach.

Creating a two-dimensional matrix from the adjacency lists is not needed. It would be the same as using adjacency matrix.
You should either sort a list of all edges by their weights (in Kruskal's algorithm), or use a heap to find a minimal vertex (in Prim's algorithm).

Related

Which Graph Algorithms prefer adjacency matrix and why?

I heard that adjacency lists are used in most graph algorithms (but not all). I'm just wondering what algorithms prefer adjacency matrices and why?
So far I’ve found that Floyd Warshall uses adjacency matrices.
Adjacency lists are generally faster than adjacency matrices in algorithms in which the key operation performed per node is “iterate over all the nodes adjacent to this node.” That can be done in time O(deg(v)) time for an adjacency list, where deg(v) is the degree of node v, while it takes time Θ(n) in an adjacency matrix. Similarly, adjacency lists make it fast to iterate over all of the edges in a graph - it takes time O(m + n) to do so, compared with time Θ(n2) for adjacency matrices.
Some of the most-commonly-used graph algorithms (BFS, DFS, Dijkstra’s algorithm, A* search, Kruskal’s algorithm, Prim’s algorithm, Bellman-Ford, Karger’s algorithm, etc.) require fast iteration over all edges or the edges incident to particular nodes, so they work best with adjacency lists.
You mentioned that Floyd-Warshall uses adjacency matrices. While Floyd-Warshall does maintain an internal matrix tracking shortest paths seen so far, it doesn’t actually require the original graph to be an adjacency matrix. The overall cost of the dynamic programming work is Θ(n3), which is bigger than the O(n2) cost of converting an adjacency list into an adjacency matrix or vice-versa.
There are only a few places where an adjacency matrix is faster than an adjacency list. Adjacency matrices take time O(1) to test whether a particular edge is present in the graph, which is faster than the O(deg(v)) cost of the corresponding operation on an adjacency list. Since the cost of converting an adjacency list to an adjacency matrix is Θ(n2), the only cases where an adjacency matrix would outperform an adjacency list are in situations where (1) random access of the edges are required and (2) the total runtime of the algorithm is o(n2). I only know a few algorithms that do this. For example, there’s the celebrity-finding problem where you’re given a graph and are asked to find whether there’s a node with incoming edges from each node and outgoing edges to no nodes. This can be done in time O(n) using an adjacency matrix, faster than what can be done with an adjacency list.
(That being said, you could also use an adjacency list represented using cuckoo hash tables rather than regular lists and match the same runtime bounds as above, though with the cost of creating the adjacency list now only expected to be fast rather than actually worst-case efficient.)
The main reason I’ve found adjacency matrices to be useful is in thinking about graphs from a different perspective. For example, raising an adjacency matrix to the kth power makes a new matrix that counts the number of paths from one node to another using exactly k hops. This can be used to count and find triangles in graphs faster than the naive algorithm, for example. Similarly, the Four Russians algorithm for computing transitive closures of graphs works by representing the graph as a matrix and using some clever techniques (treating blocks of bits as integers then used in a lookup table) to outperform the naive search.
Hope this helps!

Time Complexity of Dijkstra's Algorithm when using Adjacency Matrix vs Adjacency Linked List

For a graph with v vertices and e edges, and a fringe stored in a binary min heap, the worst case runtime is O((n+e)lg(n)). However, this is assuming we use a adjacency linked list to represent the graph. Using a adjacency matrix takes O(n^2) to traverse, while a linked list representation can be traversed in O(n+e).
Therefore, would using the matrix to represent the graph change the runtime of Dijkstra's to O(n^2lg(n))?
The O(log n) cost is paid for processing edges, not for walking the graph, so if you know the actual number of edges in the graph then Dijkstra's algorithm on an adjacency matrix with min-heap is within O(n^2 + (n+e)log(n)) time.

Is there any other Data structure to represent Graph other than Adjacency List or Adjacency Matrix?

I was looking for different Data structures for representing Graph and I came accross Nvidia CUDA Toolkit and found out new way to represent graph with the help of source_indices, destination_offsets.
Fascinated by this innovative representation of graph, I searched out for other ways of representing Graphs. But not found anything new.
I was wondering if there was any other way to represent Graph other than Adjacency Matrix or Lists...
I was wondering if there was any other way to represent Graph other
than Adjacency Matrix or Lists...
There are alternatives to the adjacency list or the adjacency matrix, such as edge list, adjacency map or forward star to name a few. Given this graph (images taken from here):
this is the adjacency matrix representation:
this is the adjacency list representation:
this would be another alternative, the edge list:
and another pretty common one is the forward star representation:
If you get into this research field you will find a good number of approaches, mainly optimizations for specific cases, taking into account factors such as:
Graph size (number of nodes)
Density of the graph
Directed or undirected graph
Static or dynamic graph
Graph known at compile time or constructed at runtime
Node IDs (labeled sequentially or not)
...
These optimizations can, for example, support reordering of the nodes in a preprocessing stage to increase reference locality. There is a lot of work for shortest path algorithms, specially when calculating the shortest path in a world map.
One example of optimization would be a dynamic graph structure (Packed-Memory Graph (PMG)) which is suited for large-scale transportation networks.
There is another representation of graphs using Adjacency Set. It is very much similar to adjacency list but instead of using Linked lists, Disjoint Sets [Union-Find] are used. You can read about disjoint sets ADT here.
If E is the number of edges and V is the number of vertices in the graph, then Adjacency set representation of graph takes up (E+V) space.
Complexities of other operations while using adjacency set representation:
Checking edge between vertex v and w : log(Degree(v))
Iterate over edges incident to vertex v: Degree(v)

Kruskal's Algorithm - Modify to matrix data structure?

This version of Kruskal's algorithm represents the edges with a adjacency list.
How would I modify the pseudo-code to instead use a adjacency matrix?
I was thinking you we would need to use the weight of edges for instance (i,j), as long as its not zero. Assigning the vertices to i,j. I may be a bit confused on this pseudo-code of Kruskals.
As pointed out by Henry the pseudocode did not specify what concrete data structures to be used. It just appears that the adjacency list representation of graph is more convenient than the adjacency matrix representation in this case.
For adjacency matrix, you simply have to scan every entries of your matrix to sort the edges of graph G on line 4. And you are doing exactly the same thing when using the adjacency list representation.
In your case you may, for example, use a PriorityQueue to sort the edges by weight in non-decreasing order and discard entries with disconnected vertices. You can then iterate this data structure in the for-loop on line 5.

Dijkstra's algorithm vs relaxing edges in topologically sorted graph for DAG

I was reading Introduction To Algorithms 3rd Edition. There are 3 methods given to solve the problem. My inquiry is about two of them.
The one with no name
The algorithm starts by topologically sorting the dag (see Section 22.4) to impose a linear ordering on the vertices. If the dag contains a path from vertex u to vertex v, then u precedes v in the topological sort. We make just one pass over the vertices in the topologically sorted order. As we process each vertex, we relax each edge that leaves the vertex.
Dijkstra's Algorithm
This is quite well known
As far as the book shows, time complexity of without name one is O(V+E) but of Dijstra's is O(ElogV). We cannot use Dijkstra's on negative weight but we can use the other. What are the advantages of using Dijkstra's Algorithm except it can be used in cyclic ones?
Because the first algorithm you give only works on acyclic graphs, whereas Dijkstra runs on graph with non-negative weight.
The limitations are not the same.
In real-world, many applications can be modelled as graphs with non-negative weights, that's why Dijkstra is so used. Plus, it is very simple to implement. The complexity of Dijkstra is higher because it relies on priority queue, but this does not mean it takes necessarily more time to execute. (nlog(n) time is not that bad, because log(n) is a relatively small number: log(10^80) = 266)
However, this stand for sparse graphs (low density of edges). For dense graphs, other algorithms may be more efficient.

Resources