Table of Contents

3.2-3.6:

Brief summary

3.2 covered graph connectivity and graph traversal, including breadth-first and depth-first searches, which determine s-t connectivity, or whether or not there is a path between s and t in a given graph. 3.3 covered implementing graph traversals using queues and stacks, but also covered the different ways to represent graphs themselves. 3.4 covered an application of BFS that tested bipartness, and 3.5 covered connectivity in directed graphs. Overall, this section wasn't too difficult for me, as it was pretty readable. However, it did admittedly get progressively more difficult. I honestly think I need more time to let it all sink in before I can conjure up concrete questions to ask.

Algorithms: brief sketches, intuitions, implementations, runtimes

Explore outward from s in all possible directions, adding nodes one “layer” at a time. Layers

Concepts:

Worst-case runtime: O(# of vertices)

General concept: start from s and try the first edge leading out. Continue this process until you reach a “dead end” = a node for which you had already explored all its neighbors. Then backtrack until you get a node with an unexplored neighbor and continue from there. Pseudocode:

  DFS(u):
      Mark u as "Explored" and add u to R
      For each edge (u,v) incedent to u
          If v is not marked "Explored" then
              Recursively invoke DFS(v)
          Endif
      Endfor

Concepts:

Stuff I want to remember

There are 2 basic ways to represent graphs:

  1. An adjacency matrix – requires O(n^2 ) space
  2. An adjacency list representation – requires only O(m+n) space

A queue is a set form which we extract elements in FIFO (first in, first out) order = the order in which they were added