Graph representations using set and hash

30 Jun, 2022
We have introduced Graph implementation using array of vectors in Graph implementation using STL for competitive programming | Set 1. In this post, a different implementation is used which can be used to implement graphs using sets. The implementation is for adjacency list representation of graph.
A set is different from a vector in two ways: it stores elements in a sorted way, and duplicate elements are not allowed. Therefore, this approach cannot be used for graphs containing parallel edges. Since sets are internally implemented as binary search trees, an edge between two vertices can be searched in O(logV) time, where V is the number of vertices in the graph. Sets in python are unordered and not indexed. Hence, for python we will be using dictionary which will have source vertex as key and its adjacency list will be stored in a set format as value for that key.
Following is an example of an undirected and unweighted graph with 5 vertices.  
Below is adjacency list representation of this graph using array of sets.  
Below is the code for adjacency list representation of an undirected graph using sets: 
C++
Java
Python3
Javascript
// A C++ program to demonstrate adjacency list// representation of graphs using sets#include <bits/stdc++.h>using namespace std; struct Graph {    int V;    set<int, greater<int> >* adjList;}; // A utility function that creates a graph of V verticesGraph* createGraph(int V){    Graph* graph = new Graph;    graph->V = V;     // Create an array of sets representing    // adjacency lists.  Size of the array will be V    graph->adjList = new set<int, greater<int> >[V];     return graph;} // Adds an edge to an undirected graphvoid addEdge(Graph* graph, int src, int dest){    // Add an edge from src to dest.  A new    // element is inserted to the adjacent    // list of src.    graph->adjList[src].insert(dest);     // Since graph is undirected, add an edge    // from dest to src also    graph->adjList[dest].insert(src);} // A utility function to print the adjacency// list representation of graphvoid printGraph(Graph* graph){    for (int i = 0; i < graph->V; ++i) {        set<int, greater<int> > lst = graph->adjList[i];        cout << endl << "Adjacency list of vertex "             << i << endl;         for (auto itr = lst.begin(); itr != lst.end(); ++itr)            cout << *itr << " ";        cout << endl;    }} // Searches for a given edge in the graphvoid searchEdge(Graph* graph, int src, int dest){    auto itr = graph->adjList[src].find(dest);    if (itr == graph->adjList[src].end())        cout << endl << "Edge from " << src             << " to " << dest << " not found."             << endl;    else        cout << endl << "Edge from " << src             << " to " << dest << " found."             << endl;} // Driver codeint main(){    // Create the graph given in the above figure    int V = 5;    struct Graph* graph = createGraph(V);    addEdge(graph, 0, 1);    addEdge(graph, 0, 4);    addEdge(graph, 1, 2);    addEdge(graph, 1, 3);    addEdge(graph, 1, 4);    addEdge(graph, 2, 3);    addEdge(graph, 3, 4);     // Print the adjacency list representation of    // the above graph    printGraph(graph);     // Search the given edge in the graph    searchEdge(graph, 2, 1);    searchEdge(graph, 0, 3);     return 0;}
// A Java program to demonstrate adjacency// list using HashMap and TreeSet// representation of graphs using setsimport java.util.*; class Graph{ // TreeSet is used to get clear// understand of graph.HashMap<Integer, TreeSet<Integer>> graph;static int v; // Graph Constructorpublic Graph(){    graph = new HashMap<>();    for(int i = 0; i < v; i++)    {        graph.put(i, new TreeSet<>());    }} // Adds an edge to an undirected graphpublic void addEdge(int src, int dest){         // Add an edge from src to dest into the set    graph.get(src).add(dest);         // Since graph is undirected, add an edge    // from dest to src into the set    graph.get(dest).add(src);} // A utility function to print the graphpublic void printGraph(){    for(int i = 0; i < v; i++)    {        System.out.println("Adjacency list of vertex " + i);        Iterator set = graph.get(i).iterator();         while (set.hasNext())            System.out.print(set.next() + " ");         System.out.println();        System.out.println();    }} // Searches for a given edge in the graphpublic void searchEdge(int src, int dest){    Iterator set = graph.get(src).iterator();     if (graph.get(src).contains(dest))        System.out.println("Edge from " + src + " to " +                           dest + " found");    else        System.out.println("Edge from " + src + " to " +                           dest + " not found");     System.out.println();} // Driver codepublic static void main(String[] args){         // Create the graph given in the above figure    v = 5;    Graph graph = new Graph();     graph.addEdge(0, 1);    graph.addEdge(0, 4);    graph.addEdge(1, 2);    graph.addEdge(1, 3);    graph.addEdge(1, 4);    graph.addEdge(2, 3);    graph.addEdge(3, 4);     // Print the adjacency list representation of    // the above graph    graph.printGraph();     // Search the given edge in the graph    graph.searchEdge(2, 1);    graph.searchEdge(0, 3);}} // This code is contributed by rexj8
# Python3 program to represent adjacency# list using dictionaryfrom collections import defaultdict class graph(object):     def __init__(self, v):                 self.v = v        self.graph = defaultdict(set)     # Adds an edge to undirected graph    def addEdge(self, source, destination):                 # Add an edge from source to destination.        # If source is not present in dict add source to dict        self.graph.add(destination)         # Add an dge from destination to source.        # If destination is not present in dict add destination to dict        self.graph[destination].add(source)     # A utility function to print the adjacency    # list representation of graph    def print(self):                 for i, adjlist in sorted(self.graph.items()):            print("Adjacency list of vertex ", i)            for j in sorted(adjlist, reverse = True):                    print(j, end = " ")                                     print('\n')                 # Search for a given edge in graph    def searchEdge(self,source,destination):                 if source in self.graph:            if destination in self.graph:                if destination in self.graph:                    if source in self.graph[destination]:                        print("Edge from {0} to {1} found.\n".format(source, destination))                        return                    else:                        print("Edge from {0} to {1} not found.\n".format(source, destination))                        return                else:                    print("Edge from {0} to {1} not found.\n".format(source, destination))                    return            else:                print("Destination vertex {} is not present in graph.\n".format(destination))                return        else:            print("Source vertex {} is not present in graph.\n".format(source))         # Driver codeif __name__=="__main__":         g = graph(5)         g.addEdge(0, 1)    g.addEdge(0, 4)    g.addEdge(1, 2)    g.addEdge(1, 3)    g.addEdge(1, 4)    g.addEdge(2, 3)    g.addEdge(3, 4)     # Print adjacenecy list    # representation of graph    g.print()     # Search the given edge in a graph    g.searchEdge(2, 1)    g.searchEdge(0, 3)  #This code is contributed by Yalavarthi Supriya
<script> // A Javascript program to demonstrate adjacency list// representation of graphs using sets class Graph {    constructor()    {        this.V = 0;        this.adjList = new Set();    }}; // A utility function that creates a graph of V verticesfunction createGraph(V){    var graph = new Graph();    graph.V = V;     // Create an array of sets representing    // adjacency lists.  Size of the array will be V    graph.adjList = Array.from(Array(V), ()=>new Set());     return graph;} // Adds an edge to an undirected graphfunction addEdge(graph, src, dest){    // Add an edge from src to dest.  A new    // element is inserted to the adjacent    // list of src.    graph.adjList[src].add(dest);     // Since graph is undirected, add an edge    // from dest to src also    graph.adjList[dest].add(src);} // A utility function to print the adjacency// list representation of graphfunction printGraph(graph){    for (var i = 0; i < graph.V; ++i) {        var lst = graph.adjList[i];        document.write( "<br>" + "Adjacency list of vertex "             + i + "<br>");         for(var item of [...lst].reverse())            document.write( item + " ");        document.write("<br>");    }} // Searches for a given edge in the graphfunction searchEdge(graph, src, dest){    if (!graph.adjList[src].has(dest))        document.write( "Edge from " + src               + " to " + dest + " not found.<br>");    else        document.write( "<br> Edge from " + src             + " to " + dest + " found." + "<br><br>");} // Driver code// Create the graph given in the above figurevar V = 5;var graph = createGraph(V);addEdge(graph, 0, 1);addEdge(graph, 0, 4);addEdge(graph, 1, 2);addEdge(graph, 1, 3);addEdge(graph, 1, 4);addEdge(graph, 2, 3);addEdge(graph, 3, 4); // Print the adjacency list representation of// the above graphprintGraph(graph); // Search the given edge in the graphsearchEdge(graph, 2, 1);searchEdge(graph, 0, 3); // This code is contributed by rutvik_56.</script>
Adjacency list of vertex 0
4 1 

Adjacency list of vertex 1
4 3 2 0 

Adjacency list of vertex 2
3 1 

Adjacency list of vertex 3
4 2 1 

Adjacency list of vertex 4
3 1 0 

Edge from 2 to 1 found.

Edge from 0 to 3 not found.
Pros: Queries like whether there is an edge from vertex u to vertex v can be done in O(log V).Cons: 
Adding an edge takes O(log V), as opposed to O(1) in vector implementation.
Graphs containing parallel edge(s) cannot be implemented through this method.
Further Optimization of Edge Search Operation using unordered_set (or hashing): The edge search operation can be further optimized to O(1) using unordered_set which uses hashing internally.
C++
// A C++ program to demonstrate adjacency list// representation of graphs using sets#include <bits/stdc++.h>using namespace std; struct Graph {    int V;    unordered_set<int>* adjList;}; // A utility function that creates a graph of// V verticesGraph* createGraph(int V){    Graph* graph = new Graph;    graph->V = V;     // Create an array of sets representing    // adjacency lists. Size of the array will be V    graph->adjList = new unordered_set<int>[V];     return graph;} // Adds an edge to an undirected graphvoid addEdge(Graph* graph, int src, int dest){    // Add an edge from src to dest. A new    // element is inserted to the adjacent    // list of src.    graph->adjList[src].insert(dest);     // Since graph is undirected, add an edge    // from dest to src also    graph->adjList[dest].insert(src);} // A utility function to print the adjacency// list representation of graphvoid printGraph(Graph* graph){    for (int i = 0; i < graph->V; ++i) {        unordered_set<int> lst = graph->adjList[i];        cout << endl << "Adjacency list of vertex "             << i << endl;         for (auto itr = lst.begin(); itr != lst.end(); ++itr)            cout << *itr << " ";        cout << endl;    }} // Searches for a given edge in the graphvoid searchEdge(Graph* graph, int src, int dest){    auto itr = graph->adjList[src].find(dest);    if (itr == graph->adjList[src].end())        cout << endl << "Edge from " << src             << " to " << dest << " not found."             << endl;    else        cout << endl << "Edge from " << src             << " to " << dest << " found."             << endl;} // Driver codeint main(){    // Create the graph given in the above figure    int V = 5;    struct Graph* graph = createGraph(V);    addEdge(graph, 0, 1);    addEdge(graph, 0, 4);    addEdge(graph, 1, 2);    addEdge(graph, 1, 3);    addEdge(graph, 1, 4);    addEdge(graph, 2, 3);    addEdge(graph, 3, 4);     // Print the adjacency list representation of    // the above graph    printGraph(graph);     // Search the given edge in the graph    searchEdge(graph, 2, 1);    searchEdge(graph, 0, 3);     return 0;}
Adjacency list of vertex 0
4 1 

Adjacency list of vertex 1
4 3 0 2 

Adjacency list of vertex 2
3 1 

Adjacency list of vertex 3
4 1 2 

Adjacency list of vertex 4
3 0 1 

Edge from 2 to 1 found.

Edge from 0 to 3 not found.
Pros: 
Queries like whether there is an edge from vertex u to vertex v can be done in O(1).
Adding an edge takes O(1).
Cons: 
Graphs containing parallel edge(s) cannot be implemented through this method.
Edges are stored in any order.
Note : adjacency matrix representation is the most optimized for edge search, but space requirements of adjacency matrix are comparatively high for big sparse graphs. Moreover adjacency matrix has other disadvantages as well like BFS and DFS become costly as we can’t quickly get all adjacent of a node. This article is contributed by vaibhav29498. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
shubhamdp2012
sailees14032000
rexj8
rutvik_56
g92ez0hprcf53bhvjokltn0cf5n4camp5gi3jvjm
om06
chandkommanaboyina
graph-basics
Graph
Hash
Hash
Graph
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.