PYTHON
Build a Graph Data Structure for Relationships
Represent and traverse relationships between entities in your web application using an adjacency list graph structure in Python, ideal for social networks, routing, or recommendation engines.
class Graph:
def __init__(self):
self.graph = {}
def add_node(self, node):
if node not in self.graph:
self.graph[node] = set() # Use a set for efficient edge storage (no duplicates)
def add_edge(self, node1, node2, directed=False):
self.add_node(node1)
self.add_node(node2)
self.graph[node1].add(node2)
if not directed:
self.graph[node2].add(node1) # For undirected graphs
def get_neighbors(self, node):
return list(self.graph.get(node, []))
def has_node(self, node):
return node in self.graph
def has_edge(self, node1, node2):
return node2 in self.graph.get(node1, set())
def __str__(self):
nodes = sorted(list(self.graph.keys()))
output = "Graph:
"
for node in nodes:
neighbors = sorted(list(self.graph[node]))
output += f" {node}: {', '.join(map(str, neighbors))}
"
return output
# Example Usage: Social Network
social_graph = Graph()
social_graph.add_edge("Alice", "Bob")
social_graph.add_edge("Bob", "Charlie")
social_graph.add_edge("Alice", "David")
social_graph.add_edge("Charlie", "Eve")
social_graph.add_edge("David", "Eve")
print(social_graph)
# Output:
# Graph:
# Alice: Bob, David
# Bob: Alice, Charlie
# Charlie: Bob, Eve
# David: Alice, Eve
# Eve: Charlie, David
print(f"Bob's friends: {social_graph.get_neighbors('Bob')}")
# Output: Bob's friends: ['Alice', 'Charlie']
print(f"Does Alice know Eve? {social_graph.has_edge('Alice', 'Eve')}")
# Output: Does Alice know Eve? False
How it works: Graphs are fundamental data structures for representing relationships, crucial in web applications like social networks, recommendation systems, or mapping services. This snippet implements a basic graph using an adjacency list representation, where each node is a key in a dictionary, and its value is a set of its neighbors. Methods for adding nodes and edges (directed or undirected), retrieving neighbors, and checking for node/edge existence are provided. This flexible structure allows developers to model complex relationships and perform traversals (e.g., finding shortest paths or connected components).