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? 5 6 2 1 diameter 9, NOT through root 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 10 BST 3 1 9 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 Definitions class 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 (t,1,3) (t,1,1) E (t,+∞,-∞) (t,1,7) 3 1 E (t,+∞,-∞) 7 E E (t,+∞,-∞) (t,+∞,-∞) (t,7,7) E (t,+∞,-∞) (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 typepreserving? 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-unifying Examples • • • • Summation: Unifying type: (int sum). Base case: Leaf: (0) fold: addition Type-unifying Examples • • • • 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-unifying Examples • 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-unifying Examples • 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-unifying Examples • CSP Formula Type: • Unifying type: (List(Pair) v) where Pair = Relation Fraction. • Fraction = <v> float. Type-unifying Examples • Tree Height, top down: • Unifying type: (int height) • fold: max Type-unifying Examples: 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-unifying Examples • Tree Height, bottom up: • Unifying type: (int height) • fold: max + 1 class 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-preserving Examples • 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-preserving Examples • 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.