Midterm CSG 110
Karl Lieberherr
Managing Software Development
• Managers of software development must first be software developers.
Tree Diameter
• The diameter of a tree T is the largest of the following quantities:– (1) diameter of T’s left subtree– (2) diameter of T’s right subtree– (3) the longest path between two leaves that
goes through the root of T (computed from the heights of the subtrees of T)
Why do we need 1 and 2?
diameter 9, NOT through root
1
2
5
6
9
Diameter
class Diameter extends IDba{ // type unifying DiameterPair combine(BSTInt l) { return new DiameterPair(0,0);} DiameterPair combine(NodeInt t, Integer d, DiameterPair l, DiameterPair r){ return // normal combine: new DiameterPair(l.get_height() + // r.get_height(), l.get_diameter() + r.get_diameter()); new DiameterPair( Math.max(l.get_height(), r.get_height())+1, Math.max(l.get_height() + r.get_height() +1, Math.max(l.get_diameter(), r.get_diameter()))); }}
Diameter
class Diameter extends IDba{ // type unifying DiameterPair combine(BSTInt l) { return new DiameterPair(0,0);} DiameterPair combine(NodeInt t, Integer d, DiameterPair l, DiameterPair r){ return // normal combine: new DiameterPair(l.get_height() + // r.get_height(), l.get_diameter() + r.get_diameter()); new DiameterPair( // recursion Math.max(l.get_height(), r.get_height())+1, // height Math.max(l.get_height() + r.get_height() +1, Math.max(l.get_diameter(), r.get_diameter()))); // diameter }}
Check BST Property
• An integer tree T, with integer n at its root, is a binary search tree (BST) if (all must hold)– the left and right tree of T are a BST– all nodes in the left tree of T are smaller than
n– all nodes in right tree of T are greater than or
equal to n
Reword: Check BST Property
• An integer tree T, with integer n at its root, is a binary search tree if (all must hold)– the left and right tree of T are a BST– the maximum of all nodes in the left tree of T
is smaller than n– the minimum of all nodes in the right tree of T
is greater than or equal to n
Why do we need the last 2?
8
1
3
9
10
BST
BST
not BST
Check for BST Property
class Check extends IDb{ Pack combine(BST l){ return new Pack(true); } Pack combine(Node t, int d, Pack lt, Pack rt){ return new Pack((lt.good && rt.good && (lt.max < d) && (d <= rt.min)), Math.min(lt.min,d), Math.max(rt.max,d)); } static boolean check(BST<Integer> tree){ return new Traversal(new Check()) .<Pack>traverse(tree).good; }}
Pack Helper Class
class Pack{ boolean good; int min,max; Pack(boolean g, int mn, int mx) { good = g; min = mn; max = mx; } Pack(boolean g){ this(g, Integer.MAX_VALUE, Integer.MIN_VALUE); }}
BST Class Definitionsclass BST<T>{ BST<T> insert(T d, Comp<T> c){ return new Node<T>(d, this, this); }
public String toString() { return new Traversal(new ToStr()).traverse(this); }}class Node<T> extends BST<T>{ T data; BST<T> left, right;
Node(T d, BST<T> l, BST<T> r){ data = d; left = l; right = r; } BST<T> insert(T d, Comp<T> c){ if(c.comp(d, data)) return new Node<T>(data, left.insert(d,c), right); return new Node<T>(data, left, right.insert(d,c)); }}
Example
5
E
1
73
E
E E E
(t,+∞,-∞) (t,+∞,-∞)
(t,+∞,-∞)
(t,1,1)
(t,1,3)
(t,+∞,-∞) (t,+∞,-∞)
(t,7,7)
(t,1,7)
(t/f,min,max) for entire tree.min and max are only valid if tree is BST.
Recursion
• without abstracting traversal
• with abstracting traversal
Recipe for writing DemeterF programs
• combine method is activated when all subtraversals have returned.
• apply method is activated when combine method at the same node mis complete.
• update method is activated when the update method of the parent is complete.
Is the task type-unifying or type-preserving?
Type-unifying• We need to find the unifying type which
may contain many more elements than only what we need to compute.
• We want a type T = (U1, U2, ...) so that T carries just enough information to implement combine T combine (X x, T t1, T t2, ...) at all nodes in the structure.
Type-unifying
• We do a problem decomposition: Assuming we have the result for t1 and t2, we need to fold t1 and t2 into a T-object to be returned.
• Simple if only t1.
• Might have several results to combine.
Type-unifyingExamples
• Summation:
• Unifying type: (int sum).
• Base case: Leaf: (0)
• fold: addition
Type-unifyingExamples
• Capacity Violation:• Capacity violation of containers of items.• violation depends on weight of container.• Unifying type: (int weight, int
violationCount).• Base case: Item: (weight, 0)• fold: vector addition
Type-unifyingExamples
• Binary Search Tree Property:• Given a binary tree of ints, are all nodes in the left tree
smaller than the root and all nodes in the right subtree greater to or equal than the root.
• Consider the maximum max of the left subtree and the minimum min of the right subtree to do the max < d <= min check.
• Unifying type: (boolean BSTproperty, int min, int max)• Base case: Empty tree: (true, +oo, -oo)• fold: operation on two triples.
Type-unifyingExamples
• Tree Diameter:
• height is needed to compute the longest path through root
• Unifying type: (int diameter, int height)
• Base case: Empty tree: (0,0)
• fold: operation on two pairs.
Type-unifyingExamples
• CSP Formula Type:
• Unifying type: (List(Pair) v) where Pair = Relation Fraction.
• Fraction = <v> float.
Type-unifyingExamples
• Tree Height, top down:
• Unifying type: (int height)
• fold: max
Type-unifyingExamples: Height
• In this top-down computation of the height, we use a separate class called Down* to avoid confusion with other arguments that are not related to sending information down.
• This is a good programming practice.
// DownHeight = <height> int.class Height3 extends IDba{ DownHeight update(NodeInt n, DownHeight h){ return new DownHeight(h.get_height()+1); } int combine(NodeInt t, int d, int l, int r)
{ return Math.max(l,r); } int combine(BSTInt l, DownHeight h){ return
h.get_height(); }}
Type-unifyingExamples
• Tree Height, bottom up:• Unifying type: (int height)• fold: max + 1class Height2 extends IDb{ int combine(NodeInt t, int d, int l, int r){ return Math.max(l,r)+1; } int combine(BSTInt l) { return 0; }}
Type-preserving
• What are the exceptions?
• Put the exceptions into apply methods if the default combine at the same node is needed.
• Otherwise put exception into combine method.
Type-preservingExamples
• Node Increment:• use apply method to increment each int by
m.;; Tree increment(define (Tree-add t m) (traverse t (extend-IDf ((number) (n) (+ n m))) Bc IDa everywhere))
Type-preservingExamples
• Reverse Binary Search Tree:
• Write combine method which swaps left and right.
Recipe Summary
• type-unifying? Find unifying type. Find fold operations.
• type-preserving? What are the exceptions?
Method Arguments in DemeterF
• We follow the rule that objects that are sent down must have a type of the form Down*.
combine arguments
• Y combine(X x, ...)
• If X has k fields, combine has at least one and at most k+2 arguments.
• Argument k+2 must be of type Down*.
• Trailing arguments are optional.
Combine arguments
class ToStr extends IDfb{ String apply(int i){ return ""+i; } String combine(NodeInt t, String d, String l, String r){ return "("+d+l+r+")"; } String combine(BSTInt l){ return ""; }}
apply arguments
• apply has one or two arguments.• Y apply(X x)• Y apply(X x, Down* d),• where X is the return type of some
combine method.class Incr extends IDf{ int apply(int i) { return i+1; } }
update arguments
• update has two arguments; the second is called the traversal argument.
• Down* update(X x, Down* d),
• where X is the type of an object that is visited while traversing down the object.
• The traversal (when called) must be passed some starting argument.