diff --git a/graphs/README.md b/graphs/README.md index f583d17..87ae04b 100644 --- a/graphs/README.md +++ b/graphs/README.md @@ -3,17 +3,23 @@
* graph is a non-linear data structure consisting of vertices and edges. + * graphs can be represented by adjacent matrices, adjacent lists, and hash table of hash tables. + * in **undirected graphs**, the edges between any two vertices do not have a direction, indicating a two-way relationship. + * in **directed graphs**, the edges between any two vertices are directional. + * in **weighted graphs**, each edge has an associated weight. if the sum of the weights of all edges of a cycle is a negative values, it's a negative weight cycle. + * the **degree of a vertex** is the number of edges connecting the vertex. in directed, graphs, if the **in-dregree** of a vertex is `d`, there are **d** directional edges incident to the vertex (and similarly, **out-degree** from the vertex). + * with `|V|` the number of vertices and `|E|` is the number of edges, search in a graph (either bfs of dfs) is `O(|V| + |E|)`.
@@ -62,6 +68,60 @@ def bfs(matrix):
+* or as a class: + +
+ +```python + +from collections import deque + + +class Graph: + + def __init__(self, edges, n): + + self.adj_list = [[] for _ in range(n)] + + for (src, dest) in edges: + self.adj_list[src].append(dest) + self.adj_list[dest].append(src) + + +def bfs(graph, v, discovered): + + queue = deque(v) + discovered[v] = True + + while queue: + + v = queue.popleft() + print(v, end=' ') + + for u in graph.adj_list[v]: + if not discovered[u]: + discovered[u] = True + queue.append(u) + + +def recursive_bfs(graph, queue, discovered): + + if not queue: + return + + v = queue.popleft() + print(v, end=' ') + + for u in graph.adj_list[v]: + if not discovered[u]: + discovered[u] = True + queue.append(u) + + recursive_bfs(graph, queue, discovered) +``` + +
+ ---- #### depth first search @@ -95,4 +155,56 @@ def dfs(matrix): for j in range(cols): traverse(i, j) ``` + +
+ +* or as a class: + +
+ +```python +from collections import deque + +class Graph: + + def __init__(self, edges, n): + + self.adj_list = [[] for _ in range(n)] + + for (src, dest) in edges: + self.adj_list[src].append(dest) + self.adj_list[dest].append(src) + + +def dfs(graph, v, discovered): + + discovered[v] = True + print(v, end=' ') + + for u in graph.adj_list[v]: + if not discovered[u]: # + dfs(graph, u, discovered) + + + +def iterative_dfs(graph, v, discovered): + + stack = [v] + + while stack: + + v = stack.pop() + + if discovered[v]: + continue + + discovered[v] = True + print(v, end=' ') + + adj_list = graph.adjList[v] + for i in reversed(range(len(adj_list))): + u = adj_list[i] + if not discovered[u]: + stack.append(u) +```