Graph representations using set and hash
Last Updated :
08 Mar, 2023
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 <bits/stdc++.h>
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<Integer, TreeSet<Integer> > 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[source].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
<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 vertices
function 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 graph
function 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 graph
function 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 graph
function 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 figure
var 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 graph
printGraph(graph);
// Search the given edge in the graph
searchEdge(graph, 2, 1);
searchEdge(graph, 0, 3);
// This code is contributed by rutvik_56.
</script>
Output
Adjacency list of vertex 0
1 4
Adjacency list of vertex 1
0 2 3 4
Adjacency list of vertex 2
1 3
Adjacency list of vertex 3
1 2 4
Adjacency list of vertex 4
0 1 3
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.
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 <bits/stdc++.h>
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<Integer>[] adjList;
public Graph(int V)
{
this.V = V;
adjList = new HashSet[V];
for (int i = 0; i < V; i++) {
adjList[i] = new HashSet<Integer>();
}
}
// 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<Integer> 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
<script>
// A JavaScript program to demonstrate adjacency list
// representation of graphs using sets
// Struct to represent a graph
class Graph {
constructor(V) {
this.V = V;
this.adjList = new Array(V).fill().map(() => new Set());
}
}
// Adds an edge to an undirected graph
function 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 graph
function printGraph(graph) {
for (let i = 0; i < graph.V; ++i) {
const lst = graph.adjList[i];
console.log(`\nAdjacency list of vertex ${i}\n`);
for (const element of lst) {
console.log(element);
}
}
}
// Searches for a given edge in the graph
function searchEdge(graph, src, dest) {
if (graph.adjList[src].has(dest)) {
console.log(`\nEdge from ${src} to ${dest} found.\n`);
} else {
console.log(`\nEdge from ${src} to ${dest} not found.\n`);
}
}
// Test code
// Create the graph given in the above figure
const V = 5;
const graph = new Graph(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);
</script>
Output
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.
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.
Similar Reads
Union and Intersection of two Graphs
Given two graphs G1 and G2, the task is to find the union and intersection of the two given graphs, i.e. (G1 ⪠G2) and (G1 ⩠G2). Examples: Input: G1 = { ("e1", 1, 2), ("e2", 1, 3), ("e3", 3, 4), ("e4", 2, 4) }, G2 = = { ("e4", 2, 4), ("e5", 2, 5), ("e6", 4, 5) }Output:G1 union G2 ise1 1 2e2 1 3e3 3
12 min read
Union and Intersection Operation On Graph
In graph theory, the data/objects belong to the same group but each piece of data differs from one other. In this article, we will see union and intersection operations on the graph. Union Operation Let G1(V1, E1) and G2(V2, E2) be two graphs as shown below in the diagram. The union of G1 and G2 is
2 min read
Implementation of Hash Table in C/C++ using Separate Chaining
Introduction: Hashing is a technique that maps a large set of data to a small set of data. It uses a hash function for doing this mapping. It is an irreversible process and we cannot find the original value of the key from its hashed value because we are trying to map a large set of data into a smal
10 min read
Maximal Independent Set in an Undirected Graph
Given an undirected graph defined by the number of vertex V and the edges E[ ], the task is to find Maximal Independent Vertex Set in an undirected graph. Independent Set: An independent set in a graph is a set of vertices which are not directly connected to each other. Note: It is a given that ther
11 min read
Implementation of Hash Table in Python using Separate Chaining
A hash table is a data structure that allows for quick insertion, deletion, and retrieval of data. It works by using a hash function to map a key to an index in an array. In this article, we will implement a hash table in Python using separate chaining to handle collisions. Components of hashing Sep
7 min read
Observations on graph
A Graph is a non-linear data structure used for the representation of a set of objects where some pairs of objects are connected. The interconnected objects are represented by points called vertices, and the line that connects the vertices are called edges. Vertices are represented by V and edges ar
4 min read
Linked List representation of Disjoint Set Data Structures
Prerequisites : Union Find (or Disjoint Set), Disjoint Set Data Structures (Java Implementation)Â A disjoint-set data structure maintains a collection S = {S1, S2,...., Sk} of disjoint dynamic sets. We identify each set by a representative, which is some member of the set. In some applications, it do
10 min read
Add and Remove vertex in Adjacency Matrix representation of Graph
A graph is a presentation of a set of entities where some pairs of entities are linked by a connection. Interconnected entities are represented by points referred to as vertices, and the connections between the vertices are termed as edges. Formally, a graph is a pair of sets (V, E), where V is a co
15+ min read
Implementation of a Hypergraph
What is Hypergraph? A hypergraph is a generalization of a graph, where an edge can connect any number of vertices. In a hypergraph, each edge is called a hyperedge and can connect any number of vertices, instead of just two vertices like in a traditional graph. A hypergraph is represented by H(E, V)
5 min read
Mathematics | Graph Theory Basics - Set 1
A Graph is just a way to show connections between things. It is set of edges and vertices where each edge is associated with unordered pair of vertices. Graph is a data structure that is defined by two components :Node or Vertex: It is a point or joint between two lines like people, cities, or websi
5 min read