diff --git a/.gitignore b/.gitignore index 6e1079e..0f28594 100644 --- a/.gitignore +++ b/.gitignore @@ -101,3 +101,6 @@ ENV/ .mypy_cache/ .vscode + +# files +*.txt \ No newline at end of file diff --git a/algs4/depth_first_paths.py b/algs4/depth_first_paths.py index 14caf6a..b538b15 100644 --- a/algs4/depth_first_paths.py +++ b/algs4/depth_first_paths.py @@ -9,7 +9,7 @@ Run depth first search on an undirected graph. Runs in O(E + V) time. - % python grapy.py tinyCG.txt + % python graph.py tinyCG.txt 6 8 0: 2 1 5 1: 0 2 @@ -60,6 +60,7 @@ def path_to(self, v): path.push(s) return path + if __name__ == '__main__': import sys f = open(sys.argv[1]) diff --git a/algs4/nonrecursive_depth_first_paths.py b/algs4/nonrecursive_depth_first_paths.py new file mode 100644 index 0000000..ed15f96 --- /dev/null +++ b/algs4/nonrecursive_depth_first_paths.py @@ -0,0 +1,92 @@ +""" + Execution: python nonrecursive_depth_first_paths.py G s + + Data files: https://algs4.cs.princeton.edu/41graph/tinyCG.txt + https://algs4.cs.princeton.edu/41graph/tinyG.txt + https://algs4.cs.princeton.edu/41graph/mediumG.txt + https://algs4.cs.princeton.edu/41graph/largeG.txt + + Run nonrecurisve depth-first search on an undirected graph. + Runs in O(E + V) time using O(V) extra space. + + % python graph.py tinyCG.txt + 6 8 + 0: 2 1 5 + 1: 0 2 + 2: 0 1 3 4 + 3: 5 4 2 + 4: 3 2 + 5: 3 0 + + % python nonrecursive_depth_first_paths.py tinyCG.txt 0 + 0 to 0: 0 + 0 to 1: 0-2-1 + 0 to 2: 0-2 + 0 to 3: 0-2-3 + 0 to 4: 0-2-3-4 + 0 to 5: 0-2-3-5 + +""" +from algs4.stack import Stack +from algs4.graph import Graph + + +class NRDepthFirstPaths: + + def __init__(self, G, s): + self.marked = [False for _ in range(G.V)] + self.edge_to = [0 for _ in range(G.V)] + self.s = s + + stack = Stack() + stack.push(s) + + while not stack.is_empty(): + v = stack.peek() + stack.pop() + + if not self.marked[v]: + self.marked[v] = True + + for node in G.adj[v]: + if not self.marked[node]: + self.edge_to[node] = v + stack.push(node) + + def has_path_to(self, v): + return self.marked[v] + + def path_to(self, v): + if not self.has_path_to(v): + return + path = Stack() + x = v + while x != self.s: + path.push(x) + x = self.edge_to[x] + path.push(s) + return path + + +if __name__ == '__main__': + import sys + f = open(sys.argv[1]) + s = int(sys.argv[2]) + V = int(f.readline()) + E = int(f.readline()) + g = Graph(V) + for i in range(E): + v, w = f.readline().split() + g.add_edge(v, w) + dfs = NRDepthFirstPaths(g, s) + for v in range(g.V): + if dfs.has_path_to(v): + print("%d to %d: " % (s, v), end='') + for x in dfs.path_to(v): + if x == s: + print(x, end='') + else: + print('-%s' % x, end='') + print() + else: + print("%d and %d: not connected" % (s, v)) diff --git a/algs4/nonrecursive_depth_first_search.py b/algs4/nonrecursive_depth_first_search.py new file mode 100644 index 0000000..6ee8dcb --- /dev/null +++ b/algs4/nonrecursive_depth_first_search.py @@ -0,0 +1,62 @@ +""" + Execution: python nonrecursive_depth_first_search.py filename.txt s + Data files: https: // algs4.cs.princeton.edu / 41graph / tinyG.txt + https: // algs4.cs.princeton.edu / 41graph / mediumG.txt + + Run nonrecurisve depth-first search on an undirected graph. + Runs in O(E + V) time using O(V) extra space. + + % python nonrecursive_depth_first_search.py tinyG.txt 0 + 0 1 2 3 4 5 6 + NOT connected + + % python nonrecursive_depth_first_search.py tinyG.txt 9 + 9 10 11 12 + NOT connected + + """ + +from algs4.graph import Graph +from algs4.stack import Stack + + +class NRDepthFirstSearch: + + def __init__(self, G, s): + self.marked = [False for _ in range(G.V)] + self.count = 0 + + stack = Stack() + stack.push(s) + + while not stack.is_empty(): + v = stack.peek() + stack.pop() + + if not self.marked[v]: + self.marked[v] = True + self.count += 1 + + for node in G.adj[v]: + if not self.marked[node]: + stack.push(node) + + +if __name__ == '__main__': + import sys + f = open(sys.argv[1]) + s = int(sys.argv[2]) + V = int(f.readline()) + E = int(f.readline()) + g = Graph(V) + for i in range(E): + v, w = f.readline().split() + g.add_edge(v, w) + search = NRDepthFirstSearch(g, s) + for v in range(g.V): + if search.marked[v]: + print(str(v) + " ") + if search.count == g.V: + print("connected") + else: + print("not connected") diff --git a/algs4/stack.py b/algs4/stack.py index 6198da8..d40871d 100644 --- a/algs4/stack.py +++ b/algs4/stack.py @@ -43,6 +43,11 @@ def pop(self): self.n -= 1 return item + def peek(self): + if self.is_empty(): + raise ValueError("Stack underflow") + return self.first.item + if __name__ == '__main__': import sys