### CS201 - Spring 2014 - Class 33

• 2D (and higher) arrays in java
- Two approaches to creating:

int[][] matrix = int[rows][cols];

or

int[][] matrix = int[row][];

for( int i = 0; i < rows; i ++ ){
matrix[i] = new int[cols];
}

- Why might we ever do the latter approach?
- if you want to have different number of columns per row, you can create each row independently.

- accessing elements works just like a normal array:

matrix[0][0] // first row, first column

matrix[1][4] // second row (at index 1), 5th column (at index 4)

- In theory, there is NO limit to the number of dimensions you can have for an array in java
- HOWEVER, most JVMs, limit it to 255, that is

int[][][].....[] // 255 of '[]'

• graph terminology clarified
- path: a path is a list of vertices p_1, p_2, ..., p_k where there exists an edge (p_i, p_{i+1}) in E
- simple path: a path where all vertices are unique, except possibly the start and end
- cycle: a path where p_1 = p_k AND the edges are unique (this avoids the problem of calling A, B, A a cycle in an undirected graph)
- note that in a directed graph A, B, A would be considered a cycle (if those edges existed) since they're separate edges (A->B and B->A)

• finding cycles
- given a connected, undirected graph, how can we determine if it has a cycle in it?
- or, given a connected graph, determine that it is not a tree
- what is the definition of a cycle?
- a path, where the endpoints are the same
- idea:
- start at a node, go down a path
- stop when either we find a vertex on the path that we've already seen
- or when we hit a dead-end
- if we hit a dead-end, backtrack and find another path
- if we visit all of the nodes, without finding a repeat vertex, it's acyclic
- does this sound like anything we've seen before?
- depth first search!

• depth first search
- look at dfsRecursive method in GraphAlgorithms code
- creates a set of the things that have been visited
- then calls dfsHelper on the start node with the visited set
- dfsHelper
- add it to the set of visited things
- for each neighbor:
- if it hasn't been visited yet, call dfsHelper
- what is the run-time of dfs on a graph?
- how many times do we call dfsHelper?
- one time for each vertex (assuming it's connected)
- what is the cost of each call to dfsHelper?
- depends on how the graph is stored!
- we need to traverse all V entries to get the neighbors
- O(|V|)
- O(|V|^2) overall
- a little trickier
- how many times do we process each edge?
- once over the lifetime of the call of dfs
- O(|V| + |E|), which for a connected graph is O(|E|)

• finding cycles as dfs
- what modifications need to be made?
- if we visit a node that we've already visited, then we've found a cycle
- what about where we just came from?
- need to know where we came from so we can avoid calling that a cycle
- want to return true if we find a cycle, false otherwise
- look at hasCycle method in GraphAlgorithms code

- observations:
- what does it do?
- runs depth first search
- if it finds a visited node that was not it's parent (i.e. a cycle) returns true
- otherwise, false
- how is this different from DFS that we saw before?
- we have the additional else if to see if we've found a cycle
- why do we need the parent as a parameter?
- so we can distinguish finding a visited node in a cycle vs. a visited node where we just came from
- what does "foundCycle = foundCycle || dfsCycle(v, u)" do?
- true if we find a cycle anywhere

- walk through an example
- what is the running time?
- basically just DFS!