diff --git a/DIRECTORY.md b/DIRECTORY.md
index c90043aa734f..fce4e4273066 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -231,6 +231,7 @@
   * [Breadth First Search Shortest Path](https://github.com/TheAlgorithms/Python/blob/master/graphs/breadth_first_search_shortest_path.py)
   * [Check Bipartite Graph Bfs](https://github.com/TheAlgorithms/Python/blob/master/graphs/check_bipartite_graph_bfs.py)
   * [Check Bipartite Graph Dfs](https://github.com/TheAlgorithms/Python/blob/master/graphs/check_bipartite_graph_dfs.py)
+  * [Connected Components](https://github.com/TheAlgorithms/Python/blob/master/graphs/connected_components.py)
   * [Depth First Search](https://github.com/TheAlgorithms/Python/blob/master/graphs/depth_first_search.py)
   * [Depth First Search 2](https://github.com/TheAlgorithms/Python/blob/master/graphs/depth_first_search_2.py)
   * [Dijkstra](https://github.com/TheAlgorithms/Python/blob/master/graphs/dijkstra.py)
@@ -264,6 +265,7 @@
   * [Test Knapsack](https://github.com/TheAlgorithms/Python/blob/master/greedy_method/test_knapsack.py)
 
 ## Hashes
+  * [Adler32](https://github.com/TheAlgorithms/Python/blob/master/hashes/adler32.py)
   * [Chaos Machine](https://github.com/TheAlgorithms/Python/blob/master/hashes/chaos_machine.py)
   * [Enigma Machine](https://github.com/TheAlgorithms/Python/blob/master/hashes/enigma_machine.py)
   * [Hamming Code](https://github.com/TheAlgorithms/Python/blob/master/hashes/hamming_code.py)
diff --git a/graphs/connected_components.py b/graphs/connected_components.py
new file mode 100644
index 000000000000..b5ef8c292b29
--- /dev/null
+++ b/graphs/connected_components.py
@@ -0,0 +1,73 @@
+"""
+https://en.wikipedia.org/wiki/Component_(graph_theory)
+
+Finding connected components in graph
+
+"""
+
+test_graph_1 = {
+    0: [1, 2],
+    1: [0, 3],
+    2: [0],
+    3: [1],
+    4: [5, 6],
+    5: [4, 6],
+    6: [4, 5],
+}
+
+test_graph_2 = {
+    0: [1, 2, 3],
+    1: [0, 3],
+    2: [0],
+    3: [0, 1],
+    4: [],
+    5: [],
+}
+
+
+def dfs(graph: dict, vert: int, visited: list) -> list:
+    """
+    Use depth first search to find all vertexes
+    being in the same component as initial vertex
+    >>> dfs(test_graph_1, 0, 5 * [False])
+    [0, 1, 3, 2]
+    >>> dfs(test_graph_2, 0, 6 * [False])
+    [0, 1, 3, 2]
+    """
+
+    visited[vert] = True
+    connected_verts = []
+
+    for neighbour in graph[vert]:
+        if not visited[neighbour]:
+            connected_verts += dfs(graph, neighbour, visited)
+
+    return [vert] + connected_verts
+
+
+def connected_components(graph: dict) -> list:
+    """
+    This function takes graph as a parameter
+    and then returns the list of connected components
+    >>> connected_components(test_graph_1)
+    [[0, 1, 3, 2], [4, 5, 6]]
+    >>> connected_components(test_graph_2)
+    [[0, 1, 3, 2], [4], [5]]
+    """
+
+    graph_size = len(graph)
+    visited = graph_size * [False]
+    components_list = []
+
+    for i in range(graph_size):
+        if not visited[i]:
+            i_connected = dfs(graph, i, visited)
+            components_list.append(i_connected)
+
+    return components_list
+
+
+if __name__ == "__main__":
+    import doctest
+
+    doctest.testmod()