... start recording.
Today :
I've added one more example to my hash_table code folder, a chained list version in hash_table_again.py .
Discussion?
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.
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.
Places to read about this stuff :
lots of vocabulary, definitions, and buzzwords :
some graph search classic problems
topics to read about:
trees are a subset of graphs ... which start simple and get complicated fast :
some code examples :
I want us to look at graphs first, and then trees later.
The topics to focus on are :
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.
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).
II) "Adjacency list"
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 ...
graphviz (demo) is a great tool for making pictures of graphs ...