CS62 - Spring 2011 - Lecture 36

  • http://www.somethingofthatilk.com/index.php?id=135

  • a few notes about the assignment
       - "empty" in the code I gave you refers to the empty tree. Ideally, you only have one empty tree for all required empty trees. You can just make this a public variable and use it whenever you need an empty tree (e.g. in the constructors).
          - to declare a public variable you can just declare it outside of a function/method in the .cpp file:
             BinaryTree * empty = ...
       - I've given you code for clear and the big 3, you just need to move it over and use it (modulo a change or two to accommodate the empty tree)
       - if you're confused about height and depth, look in the notes for binary trees   

  • Admin
       - Seniors taking exam early
       - keep looking at the homework problems!

  • graphs
       - A graph is a set of vertices (or nodes) V and a set of edges (u,v) in E where u, v are in V
       - there are different types of graphs (show some examples)
          - undirected
             - if an edge (u, v) exists (that is u is connected to v) then (v, u) also exits, that is, v is connected to u
             - when drawn, we'd draw the edge between u and v as a line
          - directed
             - edges have a direction, that is, u may be connected to v, but not necessarily vice versa
             - when drawn, we'd draw the edge from u to v as an "arrow"
          - weighted
             - each graph edge has an associated weight
             - can have either weighted, undirected graphs or weighted, directed graphs
       - graph terminology
          - path
             - a path is a list of edges e_1, e_2, ..., e_k where each edge exists in E
             - intuitively, it's a connection of edges
             - a "simple" path is a path where all edges are unique
          - cycle
             - a simple path with p_1 = p_k
             - look at cycles in directed and undirected graphs
             - a graph is called "acyclic" if it doesn't have any cycles in it
          - connected
             - a graph is connected if every pair of vertices is connected by a path
             - for directed graphs, this is called "strongly connected"
             - "weakly connected"?
                - if replacing all of the directed edges with undirected edges leaves a connected graph
       - where have we seen graphs in this class already?
          - tree
             - undirected
             - acyclic
             - note that we have to specify a root
       - some other special cases
          - twig
          - ring
          - complete graph
             - an edge exists between every node
          - bipartite graph
             - a graph where every vertex can be partitioned into two disjoint sets X and Y, such that all edges connect a vertex u in X to a vertex v in Y   
       - what are some questions we might want to ask about graphs?
          - does it have a cycle?
          - is it connected? strongly connected? weakly connected?
          - is there a path from a to b?
          - what is the shortest path from a to b?
          - do two graphs have the same structure (these are called isomorphic graphs)?

       - where do graphs come up in real life?
          - transportation networks (flights, roads, etc.)
             - flights
                - directed or undirected?
                - weighted?
                - what are the weights?
             - google maps
                - directed or undirected
                - weighted?
                - what are the weights?
          - communication networks
             - computer networks
             - phone networks
          - web
             - what are the vertices and edges?
                - vertices are web pages
                - edges are links
          - social networks
             - what are the vertices and edges?
                - vertices are people
                - edges are relationships (e.g. friends on facebook)
          - circuit design
          - bayesian networks

  • representing graphs
       - so far, we've drawn them on the board, but how are we going to store them for processing?
       - adjacency list
          - each vertex u in V contains a list (e.g. linked list, array list) of all the vertices v such that there exists an edge (u, v) in E, that is that there is an edge from u to v
          A: B->D
          B: A->D
          C: D
          D: A->B->C->E
          E: D

       - adjacency matrix
          - a |V| by |V| matrix A, such that A_ij is 1 if edge (i, j) is in E, 0 otherwise

           A B C D E
          A 0 1 0 1 0
          B 1 0 0 1 0
          C 0 0 0 1 0
          D 1 1 1 0 1
          E 0 0 0 1 0

          - what will the adjacency matrix look like if the graph is undirected?
             - it will be symmetric
       - examples:
          - draw the following graphs
             A: B C
             B: A C
             C: A B
             A: D
             B: D E
             C: D B
             D: A B C D E
             E: B C
              A B C
             A 1 0 0
             B 0 0 1
             C 0 1 0
       - how would we incorporate weights into both of these approaches?
          - adjacency list: just keep that additional piece of information in the linked list
          - adjacency matrix: store that value in the matrix (instead of just a 0 or a 1)
       - What are the benefits/drawbacks of each approach and when might each be useful?
          - adjacency list
             - good for sparse graphs
             - more space efficient (for sparse graphs)
             - must traverse the adjacency list to discover if an edge exists
          - adjacency matrix
             - good for dense graphs
             - constant time lookup to discover if an edge exists
             - for non-weighted graphs, only requires a boolean matrix
       - Can we get the best of both worlds (constant lookup, good sparse representation)?
       - sparse adjacency matrix
          - rather than storing adjacent vertices as a list, store as a hashtable
          - benefits/drawbacks?
             - constant time lookup
             - fairly space efficient (though some overhead with keeping the table)
             - not good for dense graphs

  • C++ for the day: initializer lists
       - anything inefficient/problematic about?

          string s;
          vector<int> v;
          int data;


       MyClass(string s, vector<int> v){
          this->s = s;
          this->v = v;
          data = 0;

       - Two basic problems:
          - our private members must be initialized to something before the constructor is called (what if we didn't assign to them... they'd still need to be valid class objects)
             - all the private members that are classes would have to have a zero parameter constructor
          - The parameters are passed to the constructor using call-by value
             - we'll call the copy constructor when the parameters are passed
             - then we'll call the operator= method to again copy the data from our formal parameter v to our private member variable
             - We don't actually need the first copy
       - Initializer lists:
          - follow the parameter list, but before the opening curly brace of the constructor
          - start with a ':'
          - look like normal constructor calls
          - comma separated
          MyClass(string s, vector<int> v) :
             s(s), v(v), data(0);

          - notice that we can do it for built-in data types as well
          - also notice that it's not just for using the copy constructor, you can use constants, etc.
       - In general, good practice
       - They are required in three cases:
          - one of the classes doesn't have a zero value constructor
          - constant data members
          - call-by reference: since we can't do copy-by reference (e.g. streams)