A graph is a non-linear data structure consisting of vertices (nodes) connected by edges. Unlike trees, graphs can have cycles, multiple paths between nodes, and connections in any direction. Graphs model relationships and networks, making them fundamental to solving real-world problems in social networks, maps, computer networks, and more.
Graphs are one of the most versatile and powerful data structures in computer science. By the end of this tutorial, you’ll understand graph terminology, types of graphs, representation methods, and when to use them.
Graphs model arbitrary relationships between objects, enabling solutions to problems like shortest paths, network flow, social connections, and dependency resolution.
What is a graph?
A graph G = (V, E) consists of:
V: Set of vertices (nodes)
E: Set of edges (connections between vertices)
Example graph:
A --- B
| |
| |
C --- D
Vertices: {A, B, C, D}
Edges: {(A,B), (A,C), (B,D), (C,D)}
Graph terminology
Basic terms:
Vertex (Node): A point in the graph
Edge: A connection between two vertices
Adjacent vertices: Vertices connected by an edge
Degree: Number of edges connected to a vertex
Path: Sequence of vertices connected by edges
Cycle: Path that starts and ends at the same vertex
Connected graph: Path exists between every pair of vertices
Types of graphs:
1. Directed vs Undirected
Undirected: Edges have no direction (bidirectional)
A --- B (can go both ways)
Directed (Digraph): Edges have direction (one-way)
classGraph {
constructor() {
this.adjacencyList=newMap();
}
// Add vertex
addVertex(vertex) {
if (!this.adjacencyList.has(vertex)) {
this.adjacencyList.set(vertex, []);
}
}
// Add edge (undirected)
addEdge(v1, v2) {
this.addVertex(v1);
this.addVertex(v2);
this.adjacencyList.get(v1).push(v2);
this.adjacencyList.get(v2).push(v1);
}
// Add directed edge
addDirectedEdge(from, to) {
this.addVertex(from);
this.addVertex(to);
this.adjacencyList.get(from).push(to);
}
// Remove edge
removeEdge(v1, v2) {
if (this.adjacencyList.has(v1)) {
this.adjacencyList.set(
v1,
this.adjacencyList.get(v1).filter(v => v!==v2)
);
}
if (this.adjacencyList.has(v2)) {
this.adjacencyList.set(
v2,
this.adjacencyList.get(v2).filter(v => v!==v1)
);
}
}
// Remove vertex
removeVertex(vertex) {
if (!this.adjacencyList.has(vertex)) return;
// Remove all edges to this vertex
for (constneighborofthis.adjacencyList.get(vertex)) {
this.removeEdge(vertex, neighbor);
}
this.adjacencyList.delete(vertex);
}
// Get neighbors
getNeighbors(vertex) {
returnthis.adjacencyList.get(vertex) || [];
}
// Display graph
display() {
for (const [vertex, neighbors] ofthis.adjacencyList) {
console.log(`${vertex} -> ${neighbors.join(', ')}`);
}
}
}
// Example usage
constgraph=newGraph();
graph.addEdge('A', 'B');
graph.addEdge('A', 'C');
graph.addEdge('B', 'D');
graph.addEdge('C', 'D');
graph.display();
// A -> B, C
// B -> A, D
// C -> A, D
// D -> B, C
classGraph:
def __init__(self):
self.adjacency_list = {}
defadd_vertex(self, vertex):
"""Add vertex"""if vertex notin self.adjacency_list:
self.adjacency_list[vertex] = []
defadd_edge(self, v1, v2):
"""Add edge (undirected)""" self.add_vertex(v1)
self.add_vertex(v2)
self.adjacency_list[v1].append(v2)
self.adjacency_list[v2].append(v1)
defadd_directed_edge(self, from_v, to_v):
"""Add directed edge""" self.add_vertex(from_v)
self.add_vertex(to_v)
self.adjacency_list[from_v].append(to_v)
defremove_edge(self, v1, v2):
"""Remove edge"""if v1 in self.adjacency_list:
self.adjacency_list[v1] = [
v for v in self.adjacency_list[v1] if v != v2
]
if v2 in self.adjacency_list:
self.adjacency_list[v2] = [
v for v in self.adjacency_list[v2] if v != v1
]
defremove_vertex(self, vertex):
"""Remove vertex"""if vertex notin self.adjacency_list:
return# Remove all edges to this vertexfor neighbor in self.adjacency_list[vertex]:
self.remove_edge(vertex, neighbor)
del self.adjacency_list[vertex]
defget_neighbors(self, vertex):
"""Get neighbors"""return self.adjacency_list.get(vertex, [])
defdisplay(self):
"""Display graph"""for vertex, neighbors in self.adjacency_list.items():
print(f"{vertex} -> {', '.join(map(str, neighbors))}")
# Example usagegraph = Graph()
graph.add_edge('A', 'B')
graph.add_edge('A', 'C')
graph.add_edge('B', 'D')
graph.add_edge('C', 'D')
graph.display()
# A -> B, C# B -> A, D# C -> A, D# D -> B, C
import java.util.*;publicclassGraph{private Map<String, List<String>> adjacencyList;publicGraph(){ adjacencyList =new HashMap<>();}// Add vertex
publicvoidaddVertex(String vertex){ adjacencyList.putIfAbsent(vertex,new ArrayList<>());}// Add edge (undirected)
publicvoidaddEdge(String v1, String v2){ addVertex(v1); addVertex(v2); adjacencyList.get(v1).add(v2); adjacencyList.get(v2).add(v1);}// Add directed edge
publicvoidaddDirectedEdge(String from, String to){ addVertex(from); addVertex(to); adjacencyList.get(from).add(to);}// Remove edge
publicvoidremoveEdge(String v1, String v2){if(adjacencyList.containsKey(v1)){ adjacencyList.get(v1).remove(v2);}if(adjacencyList.containsKey(v2)){ adjacencyList.get(v2).remove(v1);}}// Remove vertex
publicvoidremoveVertex(String vertex){if(!adjacencyList.containsKey(vertex))return;// Remove all edges to this vertex
for(String neighbor : adjacencyList.get(vertex)){ adjacencyList.get(neighbor).remove(vertex);} adjacencyList.remove(vertex);}// Get neighbors
public List<String>getNeighbors(String vertex){return adjacencyList.getOrDefault(vertex,new ArrayList<>());}// Display graph
publicvoiddisplay(){for(Map.Entry<String, List<String>> entry : adjacencyList.entrySet()){ System.out.println(entry.getKey()+" -> "+ String.join(", ", entry.getValue()));}}publicstaticvoidmain(String[] args){ Graph graph =new Graph(); graph.addEdge("A","B"); graph.addEdge("A","C"); graph.addEdge("B","D"); graph.addEdge("C","D"); graph.display();// A -> B, C
// B -> A, D
// C -> A, D
// D -> B, C
}}
Course schedule problem (detect cycle in directed graph)
Alien dictionary (topological sort)
Network delay time (weighted graph)
Minimum height trees
Reconstruct itinerary (Eulerian path)
Complexity summary
Space:
Adjacency Matrix: O(V²)
Adjacency List: O(V + E)
Time: Varies by algorithm (BFS/DFS: O(V + E))
Graphs are the most versatile data structure for modeling relationships. Master graphs and you’ll be able to solve a vast array of real-world problems from social networks to navigation systems.
Thanks for visiting
We are actively updating content to this site. Thanks for visiting! Please bookmark this page and visit again soon.