diff --git a/src/Depth_first_search/depth_first_search_class.py b/src/Depth_first_search/depth_first_search_class.py new file mode 100644 index 0000000..5cb120b --- /dev/null +++ b/src/Depth_first_search/depth_first_search_class.py @@ -0,0 +1,53 @@ +class Graph: + def __init__(self, vertices: list[int], edges:list[tuple[int, int]]) -> None: + self.vertices = vertices + self.edges = edges + self.visited_vertices = list() + self.index = 0 + + def dfs(self) -> list[int]: + self.visited_vertices = [] + states = {"white": [v for v in self.vertices], + "grey": list(), + "black": list()} + # если я правильно поняла, вершина является посещенной, если она просто попала в список grey + def dfs_step(vertex): + states["grey"].append(vertex) + self.visited_vertices.append(vertex) + states["white"].remove(vertex) + for edge in self.edges: + if vertex == edge[0]: + if edge[1] in states["white"]: + dfs_step(edge[1]) + if vertex == edge[1]: + if edge[0] in states["white"]: + dfs_step(edge[0]) + states["black"].append(vertex) + states["grey"].remove(vertex) + + for vertex in self.vertices: + if vertex in states["white"]: + dfs_step(vertex) + return self.visited_vertices + + + def __iter__(self): + class GraphIterator: + def __init__(self, visited_vertices): + self.visited_vertices = visited_vertices + self.index = 0 + + def __iter__(self): + return self + + def __next__(self): + if self.index >= len(self.visited_vertices): + raise StopIteration + vertex = self.visited_vertices[self.index] + self.index += 1 + return vertex + + if not self.visited_vertices: + self.visited_vertices = self.dfs() + + return GraphIterator(self.visited_vertices) \ No newline at end of file diff --git a/tests/test_for_depth_first_search.py b/tests/test_for_depth_first_search.py new file mode 100644 index 0000000..70d8223 --- /dev/null +++ b/tests/test_for_depth_first_search.py @@ -0,0 +1,71 @@ +from src.Depth_first_search.depth_first_search_class import Graph + +def test_linear_graph(): + """ 1 - 2 - 3 """ + graph = Graph([1, 2, 3], [(1, 2), (2, 3)]) + dfs_result = graph.dfs() + assert len(dfs_result) == 3 + assert set(dfs_result) == {1, 2, 3} + iter_result = list(graph) + assert iter_result == dfs_result + + +def test_branched_graph(): + """ 1 + / \ + 2 3 + | + 4 + """ + graph = Graph([1, 2, 3, 4], [(1, 2), (1, 3), (2, 4)]) + dfs_result = graph.dfs() + assert len(dfs_result) == 4 + assert set(dfs_result) == {1, 2, 3, 4} + assert dfs_result[0] == 1 + +def test_disconnected_graph(): + """ 1-2 3-4 """ + graph = Graph([1, 2, 3, 4], [(1, 2), (3, 4)]) + dfs_result = graph.dfs() + assert len(dfs_result) == 4 + assert set(dfs_result) == {1, 2, 3, 4} + + +def test_single_vertex(): + graph = Graph([1], []) + dfs_result = graph.dfs() + assert dfs_result == [1] + assert list(graph) == [1] + +def test_empty_graph(): + graph = Graph([], []) + dfs_result = graph.dfs() + assert dfs_result == [] + assert list(graph) == [] + + +def test_multiple_iterations(): + graph = Graph([1, 2], [(1, 2)]) + first_iter = list(graph) + second_iter = list(graph) + assert first_iter == second_iter + assert len(first_iter) == 2 + + +def test_dfs_order(): + graph = Graph([1, 2, 3, 4], [(1, 2), (2, 3), (3, 4), (1, 4)]) + dfs_result = graph.dfs() + assert len(dfs_result) == 4 + assert dfs_result[0] == 1 + assert dfs_result == [1, 2, 3, 4] + + + +def test_complex_graph(): + graph = Graph([1, 2, 3, 4, 5], [(1, 2), (1, 3), (2, 4), (3, 5), (4, 5)]) + dfs_result = graph.dfs() + assert len(dfs_result) == 5 + assert set(dfs_result) == {1, 2, 3, 4, 5} + assert dfs_result[0] == 1 + +