Spring 2021
-->

# April 8

... start recording.

Today :

• finish up with hash tables
• start working on graphs & trees (next several weeks)

## hash tables

I've added one more example to my hash_table code folder, a chained list version in hash_table_again.py .

Discussion?

## graphs & trees

Starting up a new topic!

In this context, a "graph" is a bunch of points (also called nodes) connected by lines (also called edges). Think ... facebook, all your friends, all their friends, and so on. How do you find that person you sort-of remember something about?

To start with, I think it makes sense to get a feel for the landscape here, then go deeper in a few specific places.

I've posted an assignment due a week from today. Please dive into the readings before Monday, and we'll practice some of this stuff in breakout rooms then.

# overview

This is a big important topic with many variations, and different people organize and explain it in different ways. Trees are often treated as their own topic, but really they are one sort of graph and share many features.

lots of vocabulary, definitions, and buzzwords :

• traversal (i.e. visit everything) ; search (look for something)
• recursive search; pre- vs post- traversal order
• topological sort
• properties : directed, weights, connected, acyclic
• ... and more

some graph search classic problems

• what is a "graph", and how can one be stored in a computer?
• as nodes with links (or pointers) to other nodes
• all in memory (static) or generated dynamically (like chess game positions)
• or more often an adjacency list
• how can we search a graph?

trees are a subset of graphs ... which start simple and get complicated fast :

• recursive search is an intuitive approach (maybe with backtracking)
• "balanced" trees are important for O(log n) collections - databases, filesystems
• includes game search : tic-tac-toe, solitaire puzzles, ...
• some classic tree data structures :

some code examples :

I want us to look at graphs first, and then trees later.

The topics to focus on are :

• how to store a graph in a computer, particularly the "adjacency list" or similar "object with neighbors" approach (a generalization of the linked list we did before)
• how to search the graph for something, making sure to visit each node

# the specifics

## what we've done

A linear structure :

A -- B  -- C -- D

can be stored as either

['A', 'B', 'C', 'D']       # a vanilla list

Node('A') -- .next --->   Node('B')      # a linked list

a = Node('A')
b = Node('B')
a.next = b
# or a.next='B' , along with a way to get from 'B' to b


Searching one of these is straightforward : we start at the beginning and walk through it.

## new : graph

A -- B
|    |
C -- D -- E


How do we store this ?

 I) "Adjacency matrix"
Each node gets a number 0,1,2,3,...
Put information about possible edge (i,j)
into that (row,column) of the matrix
Good for dense graphs (i.e. lots of numbers)
If N nodes, space is O(N*N).

For each node, store its neighbors in a list
... so a list of lists, essentially.
If we number nodes  (A,B,C,D,E) as (0,1,2,3,4) then
graph = [ [1,2],    # A neighbors : A-B, A-C
[1,3],    # B neighbors : B-A, B-D
[0,3],    # C neighbors : C-A, C-D
[1,2,4],  # D neighbors : D-B, D-C, D-E
[3]       # E neighbors : E-D
]
Or in python use a dictionary of dictionaries,
including "weight" of each edge (all weight=1 here)
{ 'A' : {'B':1, 'C':1},
'B' : {'A':1, 'D':1},
etc }
Or use node pointers or references to objects in list or dict,
rather than just name of node.

III) node objects with .neighbor property or method
which give either names or reference to other objects
... like what we did with the linked lists.
a = Node()
b = Node()
c = Node()
a.neighbors = [b, c]   # or ['B', 'C']


How do we search through a structure like this efficiently?

Good question ...

# aside

graphviz (demo) is a great tool for making pictures of graphs ...

https://cs.bennington.college /courses /spring2021 /algorithms /notes /graphs1