Graph Data Structure

Graph Data Structure

Initializing a Graph

When a new graph object is created using the Graph() constructor, an empty dictionary is initialized in the __init__ method:

def __init__(self):
    self.adj_list = {}

This dictionary will hold the adjacency list for the graph. The keys in the dictionary will be the vertices of the graph, and the values will be lists of the vertices that are adjacent to the key vertex.

Adding Edges to a Graph

The add_edge method adds a new edge to the graph. It takes two parameters, vertex1 and vertex2, which are the vertices that the edge connects. If either of the vertices does not exist in the graph, it is added to the graph as a key in the adj_list dictionary with an empty list as its value. Then, the other vertex is appended to the list of adjacent vertices for the first vertex.


def add_edge(self, vertex1, vertex2):
    if vertex1 not in self.adj_list:
        self.adj_list[vertex1] = []
    if vertex2 not in self.adj_list:
        self.adj_list[vertex2] = []
    self.adj_list[vertex1].append(vertex2)
    self.adj_list[vertex2].append(vertex1)

Removing Edges from a Graph

The remove_edge method removes an edge from the graph. It takes two parameters, vertex1 and vertex2, which are the vertices that the edge connects. If either of the vertices does not exist in the graph, an exception is raised. Then, the other vertex is removed from the list of adjacent vertices for the first vertex.


def remove_edge(self, vertex1, vertex2):
    if vertex1 not in self.adj_list or vertex2 not in self.adj_list:
        raise Exception("Vertices not in graph")

Removing a Vertex from a Graph

The remove_vertex method removes a vertex from the graph. It takes one parameter, vertex, which is the vertex to remove. If the vertex does not exist in the graph, an exception is raised. Then, the vertex is removed from the graph as a key in the adj_list dictionary. Finally, the vertex is removed from the list of adjacent vertices for all other vertices in the graph.


def remove_vertex(self, vertex):
    if vertex not in self.adj_list:
        raise Exception("Vertex not in graph")
    for adjacent_vertex in self.adj_list[vertex]:
        self.adj_list[adjacent_vertex].remove(vertex)
    self.adj_list.pop(vertex)

The dfs method performs a depth-first search on the graph. It takes one parameter, start, which is the starting vertex for the search. It returns a list of the vertices that were visited during the search.


def dfs(self, start):
    visited = []
    stack = Stack()
    stack.push(start)
    while not stack.is_empty():
        current_vertex = stack.pop()
        if current_vertex not in visited:
            visited.append(current_vertex)
            for adjacent_vertex in self.adj_list[current_vertex]:
                stack.push(adjacent_vertex)
    return visited

The bfs method performs a breadth-first search on the graph. It takes one parameter, start, which is the starting vertex for the search. It returns a list of the vertices that were visited during the search.


def bfs(self, start):
    visited = []
    queue = Queue()
    queue.enqueue(start)
    while not queue.is_empty():
        current_vertex = queue.dequeue()
        if current_vertex not in visited:
            visited.append(current_vertex)
            for adjacent_vertex in self.adj_list[current_vertex]:
                queue.enqueue(adjacent_vertex)
    return visited

Using the Graph Class

The following code creates a new graph object and adds some edges to it:


graph = Graph()
graph.add_edge("A", "B")
graph.add_edge("A", "C")
graph.add_edge("B", "D")

The following code performs a depth-first search on the graph, starting at vertex "A":


print(graph.dfs("A"))

The following code performs a breadth-first search on the graph, starting at vertex "A":


print(graph.bfs("A"))

Did you find this article valuable?

Support Ken's Code by becoming a sponsor. Any amount is appreciated!