package edu.neu.ccs.demeterf.examples; import edu.neu.ccs.demeterf.Traversal; import edu.neu.ccs.demeterf.ID; import edu.neu.ccs.demeterf.compose.CompTraversal; /** Height/Diameter Composition. The Height calculation (HTrip) is composed * (passed to) the Diameter calculation (int). Height is useful on it's * own... but we need to keep a little more information to support the * Diameter calc. */ public class Compose{ static BST build(int k, BST t, int a[]){ if(k >= a.length)return t; return build(k+1, t.insert(a[k]), a); } static public void main(String args[]){ BST tree = build(0, new BST(), new int[]{6,3,1,5,0,9,4,7,10,8}); System.out.print(" Tree: "+tree.toString()+"\n"); System.out.print(" Height: "+Height.height(tree)+"\n"); System.out.print(" Diam: "+Diam.diameter(tree)+"\n"); } static class BST{ BST(){} public String toString(){ return new Traversal(new ID(){ String combine(BST l){ return ""; } String combine(Node t, int d, String l, String r) {return "("+d+l+r+")"; } }).traverse(this); } BST insert(T d){ return new Node(d, this, this); } } static class Node extends BST{ T data; BST left, right; Node(T d, BST l, BST r){ data = d; left = l; right = r; } BST insert(T d){ if(d.compareTo(data) > 0) return new Node(data, left.insert(d), right); return new Node(data, left, right.insert(d)); } } // Contains current, left and right heights of a Tree. static class HTrip{ int ch,lh,rh; HTrip(){ this(0,0,0); } HTrip(int c, int l, int r){ ch = c; lh = l; rh = r; } } // Tree Height Calculation. Produces a HTrip, so that we // can use the values of current/left/right subtrees in // other calculations static class Height extends ID{ HTrip combine(BST l){ return new HTrip(); } HTrip combine(Node t, int d, HTrip l, HTrip r) { return new HTrip(1+Math.max(l.ch, r.ch),l.ch, r.ch); } // Static Height calculation (could move into BST) static int height(BST t){ return new Traversal(new Height()).traverse(t).ch; } } // Tree Diameter Calculation. The height calculation (HTrip) is passed // as the last parameter to each combine method when we compose the // two function objects into a single traversal. static class Diam extends ID{ int combine(BST l){ return 0; } int combine(Node t, int d, int l, int r, HTrip h) { return Math.max(h.lh+h.rh+1, Math.max(l,r)); } // Static Diameter calculation (could move into BST) static int diameter(BST t){ return new CompTraversal(new Height(),new Diam()).traverseLast(t); } } }