001 package brs.visitor; 002 003 import brs.*; 004 import fp.*; 005 006 /** 007 * Traverse a binary tree in order: 008 * For an empty tree: 009 * do the appropriate processing. 010 * For a non-empty tree: 011 * Traverse the left subtree in order; 012 * Process the root; 013 * Traverse the right subtree in order; 014 * 015 * Uses two lambdas as variants. 016 * Let fRight, fLeft be ILambda and b be some input object. 017 * empty case: 018 * InOrder2(empty, fRight, fLeft, b) = b; 019 * non-empty case: 020 * InOder(tree, fRight, fLeft, b) = 021 * fRight(fLeft(InOrder2(tree.left, fRight, fLeft, b), tree)), 022 * InOrder2(tree.right, fRight, fLeft, b)); 023 * @author DXN 024 * @author SBW 025 * @author Mathias Ricken - Copyright 2008 - All rights reserved. 026 * @since 09/22/2004 027 */ 028 public class InOrder2<T,P> implements IVisitor<T,P,P> { 029 // an abstract function with domain (range of InOrder2, BiTree): 030 private ILambda2<P,P,BiTree<T>> _fLeft; 031 032 // an abstract function with domain (range of _fLeft, range of InOrder2): 033 private ILambda2<P,P,P> _fRight; 034 035 036 public InOrder2(ILambda2<P,P,P> fRight, ILambda2<P,P,BiTree<T>> fLeft) { 037 _fRight = fRight; 038 _fLeft = fLeft; 039 } 040 041 042 public P emptyCase(BiTree<T> host, P... b) { 043 return b[0]; 044 } 045 046 public P nonEmptyCase(BiTree<T> host, P... b) { 047 return _fRight.apply(_fLeft.apply(host.getLeftSubTree().execute(this, b), host), 048 host.getRightSubTree().execute(this, b)); 049 } 050 051 052 public static void main(String[] nu) { 053 final ILambda2<Integer,Integer,Integer> add = 054 new ILambda2<Integer,Integer,Integer>() { 055 public Integer apply(Integer arg1, Integer arg2) { 056 return arg1+arg2; 057 } 058 }; 059 060 ILambda2<Integer,Integer,BiTree<Integer>> add2 = 061 new ILambda2<Integer,Integer,BiTree<Integer>>() { 062 public Integer apply(Integer arg1, BiTree<Integer> arg2) { 063 return add.apply(arg1,arg2.getRootDat()); 064 } 065 }; 066 067 // Add the numbers in the tree in in-order fashion: 068 InOrder2<Integer,Integer> inOrderAdd = new InOrder2<Integer,Integer>(add, add2); 069 070 071 final ILambda2<String,String,String> concat = new ILambda2<String,String,String>() { 072 public String apply(String arg1, String arg2) { 073 if ("" != arg1.toString()) { 074 if ("" != arg2.toString()) { 075 return arg1.toString() + " " + arg2.toString(); 076 } 077 else { 078 return arg1.toString(); 079 } 080 } 081 else { 082 return arg2.toString(); 083 } 084 } 085 }; 086 ILambda2<String,String,BiTree<Integer>> concat2 = new ILambda2<String,String,BiTree<Integer>>() { 087 public String apply(String arg1, BiTree<Integer> arg2) { 088 return concat.apply(arg1, arg2.getRootDat().toString()); 089 } 090 }; 091 // Concatenate the String representation of the elements in the tree 092 // in in-order fashion: 093 InOrder2<Integer,String> inOrderConcat = new InOrder2<Integer,String>(concat, concat2); 094 095 096 BiTree<Integer> bt = new BiTree<Integer>(); 097 System.out.println(bt + "\nAdd \n" + bt.execute(inOrderAdd, 0)); 098 System.out.println("In order concat \n" + bt.execute(inOrderConcat, "")); 099 100 101 bt.insertRoot(5); 102 System.out.println(bt + "\nAdd \n" + bt.execute(inOrderAdd, 0)); 103 System.out.println("In order concat \n" + bt.execute(inOrderConcat, "")); 104 105 106 bt.getLeftSubTree().insertRoot(-2); 107 System.out.println(bt + "\nAdd \n" + bt.execute(inOrderAdd, 0)); 108 System.out.println("In order concat \n" + bt.execute(inOrderConcat, "")); 109 110 111 bt.getRightSubTree().insertRoot(10); 112 System.out.println(bt + "\nAdd \n" + bt.execute(inOrderAdd, 0)); 113 System.out.println("In order concat \n" + bt.execute(inOrderConcat, "")); 114 115 116 bt.getRightSubTree().getLeftSubTree().insertRoot(-9); 117 System.out.println(bt + "\nAdd \n" + bt.execute(inOrderAdd, 0)); 118 System.out.println("In order concat \n" + bt.execute(inOrderConcat, "")); 119 } 120 }