Skip to content

Commit bf1415c

Browse files
committed
Merge pull request nryoung#39 from lcheung90/dfs
Implement Depth-First-Search algorithm
2 parents 1d809b7 + 8024d2a commit bf1415c

File tree

2 files changed

+89
-1
lines changed

2 files changed

+89
-1
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
"""
2+
depth_first_search.py
3+
4+
Recursive implementation of DFS algorithm on a graph.
5+
6+
Depth First Search Overview:
7+
------------------------
8+
Used to traverse trees, tree structures or graphs.
9+
Starts at a selected node (root) and explores the branch
10+
as far as possible before backtracking.
11+
12+
Time Complexity: O(E + V)
13+
E = Number of edges
14+
V = Number of vertices (nodes)
15+
16+
Pseudocode: https://en.wikipedia.org/wiki/Depth-first_search
17+
"""
18+
def dfs(graph,start,path = []):
19+
if start not in graph or graph[start] == None or graph[start] == []:
20+
return None
21+
path = path + [start]
22+
for edge in graph[start]:
23+
if edge not in path:
24+
path = dfs(graph, edge,path)
25+
return path

algorithms/tests/test_searching.py

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
""" Unit Tests for searching """
22
import unittest
3-
from ..searching import binary_search, kmp_search, rabinkarp_search, bmh_search
3+
from ..searching import binary_search, kmp_search, rabinkarp_search, bmh_search, depth_first_search
44

55

66
class TestBinarySearch(unittest.TestCase):
@@ -69,3 +69,66 @@ def test_bmhsearch(self):
6969
rv2 = bmh_search.search(self.string, "ABCDER")
7070
self.assertIs(rv1[0], 9)
7171
self.assertFalse(rv2)
72+
73+
class TestDepthFirstSearch(unittest.TestCase):
74+
"""
75+
Tests DFS on a graph represented by a adjacency list
76+
"""
77+
78+
def test_dfs(self):
79+
self.graph = {'A': ['B','C','E'],
80+
'B': ['A','D','F'],
81+
'C': ['A','G'],
82+
'D': ['B'],
83+
'F': ['B'],
84+
'E': ['A'],
85+
'G': ['C']}
86+
rv1 = depth_first_search.dfs(self.graph, "A")
87+
rv2 = depth_first_search.dfs(self.graph, "G")
88+
rv1e = depth_first_search.dfs(self.graph, "Z")
89+
self.assertEqual(rv1, ['A', 'B', 'D', 'F', 'C', 'G', 'E'])
90+
self.assertEqual(rv2, ['G', 'C', 'A', 'B', 'D', 'F', 'E'])
91+
self.assertEqual(rv1e, None)
92+
self.graph = {1:[2,3,4],
93+
2:[1,6,10],
94+
3:[1,5,10],
95+
4:[1,10,11],
96+
5:[3,10],
97+
6:[2,7,8,9],
98+
7:[6,8],
99+
8:[6,7],
100+
9:[6,10],
101+
10:[3,5,9,12],
102+
11:[4],
103+
12:[10]}
104+
rv3 = depth_first_search.dfs(self.graph,1)
105+
rv4 = depth_first_search.dfs(self.graph,5)
106+
rv5 = depth_first_search.dfs(self.graph,6)
107+
rv2e = depth_first_search.dfs(self.graph,99)
108+
self.assertEqual(rv3, [1, 2, 6, 7, 8, 9, 10, 3, 5, 12, 4, 11])
109+
self.assertEqual(rv4, [5, 3, 1, 2, 6, 7, 8, 9, 10, 12, 4, 11])
110+
self.assertEqual(rv5, [6, 2, 1, 3, 5, 10, 9, 12, 4, 11, 7, 8])
111+
self.assertEqual(rv2e, None)
112+
self.graph = {1:[2,3,4,5,6],
113+
2:[1,4,7,8,9],
114+
3:[1,10],
115+
4:[1,2,11,12],
116+
5:[1,13,14,15],
117+
6:[1,15],
118+
7:[2],
119+
8:[2],
120+
9:[2,10],
121+
10:[3,9],
122+
11:[4],
123+
12:[4],
124+
13:[5],
125+
14:[5],
126+
15:[5,6]}
127+
rv6 = depth_first_search.dfs(self.graph,1)
128+
rv7 = depth_first_search.dfs(self.graph,10)
129+
rv8 = depth_first_search.dfs(self.graph,5)
130+
rv3e = depth_first_search.dfs(self.graph,-1)
131+
self.assertEqual(rv6, [1, 2, 4, 11, 12, 7, 8, 9, 10, 3, 5, 13, 14, 15, 6])
132+
self.assertEqual(rv7, [10, 3, 1, 2, 4, 11, 12, 7, 8, 9, 5, 13, 14, 15, 6])
133+
self.assertEqual(rv8, [5, 1, 2, 4, 11, 12, 7, 8, 9, 10, 3, 6, 15, 13, 14])
134+
self.assertEqual(rv3e, None)

0 commit comments

Comments
 (0)