# Graph representations using set and hash

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++

 `// A C++ program to demonstrate adjacency list` `// representation of graphs using sets` `#include ` `using` `namespace` `std;`   `struct` `Graph {` `    ``int` `V;` `    ``set<``int``>* adjList;` `};`   `// A utility function that creates a graph of V vertices` `Graph* 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` `>[V];`   `    ``return` `graph;` `}`   `// Adds an edge to an undirected graph` `void` `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 graph` `void` `printGraph(Graph* graph)` `{` `    ``for` `(``int` `i = 0; i < graph->V; ++i) {` `        ``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 graph` `void` `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 code` `int` `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;` `}`

## Java

 `// A Java program to demonstrate adjacency` `// list using HashMap and TreeSet` `// representation of graphs using sets` `import` `java.util.*;`   `class` `Graph {`   `    ``// TreeSet is used to get clear` `    ``// understand of graph.` `    ``HashMap > graph;` `    ``static` `int` `v;`   `    ``// Graph Constructor` `    ``public` `Graph()` `    ``{` `        ``graph = ``new` `HashMap<>();` `        ``for` `(``int` `i = ``0``; i < v; i++) {` `            ``graph.put(i, ``new` `TreeSet<>());` `        ``}` `    ``}`   `    ``// Adds an edge to an undirected graph` `    ``public` `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 graph` `    ``public` `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 graph` `    ``public` `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 code` `    ``public` `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

 `# Python3 program to represent adjacency` `# list using dictionary` `from` `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 code` `if` `__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`

## C#

 `// A C# program to demonstrate adjacency` `// list using HashMap and TreeSet` `// representation of graphs using sets` `using` `System;` `using` `System.Collections.Generic;`   `class` `Graph {`   `    ``// TreeSet is used to get clear` `    ``// understand of graph.` `    ``Dictionary<``int``, HashSet<``int``>> graph;` `    ``static` `int` `v;`   `    ``// Graph Constructor` `    ``public` `Graph()` `    ``{` `        ``graph = ``new` `Dictionary<``int``, HashSet<``int``> >();` `        ``for` `(``int` `i = 0; i < v; i++) {` `            ``graph.Add(i, ``new` `HashSet<``int``>());` `        ``}` `    ``}`   `    ``// Adds an edge to an undirected graph` `    ``public` `void` `addEdge(``int` `src, ``int` `dest)` `    ``{`   `        ``// Add an edge from src to dest into the set` `        ``graph[src].Add(dest);`   `        ``// Since graph is undirected, add an edge` `        ``// from dest to src into the set` `        ``graph[dest].Add(src);` `    ``}`   `    ``// A utility function to print the graph` `    ``public` `void` `printGraph()` `    ``{` `        ``for` `(``int` `i = 0; i < v; i++) {` `            ``Console.WriteLine(``"Adjacency list of vertex "` `                              ``+ i);` `            ``foreach``(``int` `set_ ``in` `graph[i])` `                ``Console.Write(set_ + ``" "``);`   `            ``Console.WriteLine();` `            ``Console.WriteLine();` `        ``}` `    ``}`   `    ``// Searches for a given edge in the graph` `    ``public` `void` `searchEdge(``int` `src, ``int` `dest)` `    ``{` `        ``// Iterator set = graph.get(src).iterator();`   `        ``if` `(graph[src].Contains(dest))` `            ``Console.WriteLine(``"Edge from "` `+ src + ``" to "` `                              ``+ dest + ``" found"``);` `        ``else` `            ``Console.WriteLine(``"Edge from "` `+ src + ``" to "` `                              ``+ dest + ``" not found"``);`   `        ``Console.WriteLine();` `    ``}`   `    ``// Driver code` `    ``public` `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 Abhijeet Kumar(abhijeet19403)`

## Javascript

 ``

Output

```Adjacency list of vertex 0
1 4

0 2 3 4

1 3

1 2 4

0 1 3

Edge from 2 to 1 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.

Space Complexity: O(V+E), where V is the number of vertices and E is the number of edges in the graph. This is because the code uses an adjacency list to store the graph, which takes linear space.

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.

Implementation:

## C++

 `// A C++ program to demonstrate adjacency list` `// representation of graphs using sets` `#include ` `using` `namespace` `std;`   `struct` `Graph {` `    ``int` `V;` `    ``unordered_set<``int``>* adjList;` `};`   `// A utility function that creates a graph of ` `// V vertices` `Graph* 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 graph` `void` `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 graph` `void` `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 graph` `void` `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 code` `int` `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;` `}`

## Java

 `import` `java.util.HashSet;` `import` `java.util.Set;`   `class` `Graph {` `  ``int` `V;` `  ``Set[] adjList;`   `  ``public` `Graph(``int` `V)` `  ``{` `    ``this``.V = V;` `    ``adjList = ``new` `HashSet[V];` `    ``for` `(``int` `i = ``0``; i < V; i++) {` `      ``adjList[i] = ``new` `HashSet();` `    ``}` `  ``}`   `  ``// Adds an edge to an undirected graph` `  ``void` `addEdge(``int` `src, ``int` `dest)` `  ``{`   `    ``// Add an edge from src to dest. A new` `    ``// element is inserted to the adjacent` `    ``// list of src.` `    ``adjList[src].add(dest);`   `    ``// Since graph is undirected, add an edge` `    ``// from dest to src also` `    ``adjList[dest].add(src);` `  ``}`   `  ``// A utility function to print the adjacency` `  ``// list representation of graph` `  ``void` `printGraph()` `  ``{` `    ``for` `(``int` `i = ``0``; i < V; i++) {` `      ``Set lst = adjList[i];` `      ``System.out.println(``"Adjacency list of vertex "` `                         ``+ i);` `      ``for` `(Integer itr : lst) {` `        ``System.out.print(itr + ``" "``);` `      ``}` `      ``System.out.println();` `    ``}` `  ``}`   `  ``// Searches for a given edge in the graph` `  ``void` `searchEdge(``int` `src, ``int` `dest)` `  ``{` `    ``if` `(!adjList[src].contains(dest)) {` `      ``System.out.println(``"Edge from "` `+ src + ``" to "` `                         ``+ dest + ``" not found."``);` `    ``}` `    ``else` `{` `      ``System.out.println(``"Edge from "` `+ src + ``" to "` `                         ``+ dest + ``" found."``);` `    ``}` `  ``}` `}`   `public` `class` `Main {` `  ``public` `static` `void` `main(String[] args)` `  ``{`   `    ``// Create the graph given in the above figure` `    ``int` `V = ``5``;` `    ``Graph graph = ``new` `Graph(V);` `    ``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 divya_p123.`

## Python3

 `import` `collections`   `class` `Graph:` `    ``def` `__init__(``self``, V):` `        ``self``.V ``=` `V` `        ``self``.adjList ``=` `[``set``() ``for` `_ ``in` `range``(V)]`   `    ``def` `add_edge(``self``, src, dest):` `        ``self``.adjList[src].add(dest)` `        ``self``.adjList[dest].add(src)`   `    ``def` `print_graph(``self``):` `        ``for` `i ``in` `range``(``self``.V):` `            ``print``(``"Adjacency list of vertex {}"``.``format``(i))` `            ``for` `vertex ``in` `self``.adjList[i]:` `                ``print``(vertex, end``=``' '``)` `            ``print``()`   `    ``def` `search_edge(``self``, src, dest):` `        ``if` `dest ``in` `self``.adjList[src]:` `            ``print``(``"Edge from {} to {} found."``.``format``(src, dest))` `        ``else``:` `            ``print``(``"Edge from {} to {} not found."``.``format``(src, dest))`     `# Driver code` `if` `__name__ ``=``=` `"__main__"``:` `    ``V ``=` `5` `    ``graph ``=` `Graph(V)` `    ``graph.add_edge(``0``, ``1``)` `    ``graph.add_edge(``0``, ``4``)` `    ``graph.add_edge(``1``, ``2``)` `    ``graph.add_edge(``1``, ``3``)` `    ``graph.add_edge(``1``, ``4``)` `    ``graph.add_edge(``2``, ``3``)` `    ``graph.add_edge(``3``, ``4``)`   `    ``# Print the adjacency list representation of the above graph` `    ``graph.print_graph()`   `    ``# Search the given edge in the graph` `    ``graph.search_edge(``2``, ``1``)` `    ``graph.search_edge(``0``, ``3``)`

## C#

 `using` `System;` `using` `System.Collections.Generic;`   `class` `Graph {` `  ``int` `V;` `  ``HashSet<``int``>[] adjList;`   `  ``public` `Graph(``int` `V)` `  ``{` `    ``this``.V = V;` `    ``adjList = ``new` `HashSet<``int``>[ V ];` `    ``for` `(``int` `i = 0; i < V; i++) {` `      ``adjList[i] = ``new` `HashSet<``int``>();` `    ``}` `  ``}`   `  ``// Adds an edge to an undirected graph` `  ``void` `addEdge(``int` `src, ``int` `dest)` `  ``{`   `    ``// Add an edge from src to dest. A new` `    ``// element is inserted to the adjacent` `    ``// list of src.` `    ``adjList[src].Add(dest);`   `    ``// Since graph is undirected, add an edge` `    ``// from dest to src also` `    ``adjList[dest].Add(src);` `  ``}`   `  ``// A utility function to print the adjacency` `  ``// list representation of graph` `  ``void` `printGraph()` `  ``{` `    ``for` `(``int` `i = 0; i < V; i++) {` `      ``HashSet<``int``> lst = adjList[i];` `      ``Console.WriteLine(``"Adjacency list of vertex "` `                        ``+ i);` `      ``foreach``(``int` `itr ``in` `lst)` `      ``{` `        ``Console.Write(itr + ``" "``);` `      ``}` `      ``Console.WriteLine();` `    ``}` `  ``}`   `  ``// Searches for a given edge in the graph` `  ``void` `searchEdge(``int` `src, ``int` `dest)` `  ``{` `    ``if` `(!adjList[src].Contains(dest)) {` `      ``Console.WriteLine(``"Edge from "` `+ src + ``" to "` `                        ``+ dest + ``" not found."``);` `    ``}` `    ``else` `{` `      ``Console.WriteLine(``"Edge from "` `+ src + ``" to "` `                        ``+ dest + ``" found."``);` `    ``}` `  ``}`   `  ``public` `static` `void` `Main(``string``[] args)` `  ``{`   `    ``// Create the graph given in the above figure` `    ``int` `V = 5;` `    ``Graph graph = ``new` `Graph(V);` `    ``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 YASH` `// AGARWAL(YASHAGARWAL2852002)`

## Javascript

 ``

Output

```Adjacency list of vertex 0
4 1

4 3 2 0

3 1

4 2 1

3 1 0

Edge from 2 to 1 found.

```

Time Complexity: The time complexity of creating a graph using adjacency list is O(V + E), where V is the number of vertices and E is the number of edges in the graph.

Space Complexity: The space complexity of creating a graph using adjacency list is O(V + E), where V is the number of vertices and E is the number of edges in the graph.

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.

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.

Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!

Previous
Next