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)
+```