package brs.visitor; import brs.*; /** * Implements Sleator and Tarjan's top-down splay algorithm. Returns * the BiTree containing the given key Object. If, however, that * key Object is not found in the BST, returns a BiTree that is * adjacent to the key Object, coming before or after it. * * @author Alan L. Cox */ public class BSTSplay implements IVisitor { public static final BSTSplay Singleton = new BSTSplay(); private BSTSplay() { } /** * @param host an empty binary search tree * @param input not used * @return the host */ public Object emptyCase(BiTree host, Object input) { return (host); } /** * @param host a non-empty binary search tree * @param input the key Object * @return null or a BiTree whose key is equal or close to input */ public Object nonEmptyCase(BiTree host, final Object input) { class Helper { BiTree _dummy; BiTree _leftSubTreeMax; BiTree _rightSubTreeMin; Helper() { _dummy = new BiTree(); _dummy.insertRoot(null); _leftSubTreeMax = _dummy; _rightSubTreeMin = _dummy; } void setLeftSubTreeMax(BiTree bt) { _leftSubTreeMax.setRightSubTree(bt); _leftSubTreeMax = bt; } void setRightSubTreeMin(BiTree bt) { _rightSubTreeMin.setLeftSubTree(bt); _rightSubTreeMin = bt; } BiTree getLeftSubTree() { return (_dummy.getRightSubTree()); } BiTree getRightSubTree() { return (_dummy.getLeftSubTree()); } } final Helper helper = new Helper(); class Outer implements IVisitor { public Object emptyCase(BiTree child, Object root) { return (root); } public Object nonEmptyCase(BiTree root, Object notUsed) { if (((Comparable)input).compareTo(root.getRootDat()) < 0) { BiTree child = root.getLeftSubTree(); return (child.execute(new IVisitor() { public Object emptyCase(BiTree child, Object root) { return (root); } public Object nonEmptyCase(BiTree child, Object root) { if (((Comparable)input).compareTo(child.getRootDat()) < 0) { /* Rotate right. */ ((BiTree)root).setLeftSubTree(child.getRightSubTree()); child.setRightSubTree((BiTree)root); root = child; child = ((BiTree)root).getLeftSubTree(); } return (child.execute(new IVisitor() { public Object emptyCase(BiTree child, Object root) { return (root); } public Object nonEmptyCase(BiTree child, Object root) { helper.setRightSubTreeMin((BiTree)root); return (child.execute(Outer.this, root)); } }, root)); } }, root)); } else if (((Comparable)input).compareTo(root.getRootDat()) > 0) { BiTree child = root.getRightSubTree(); return (child.execute(new IVisitor() { public Object emptyCase(BiTree child, Object root) { return (root); } public Object nonEmptyCase(BiTree child, Object root) { if (((Comparable)input).compareTo(child.getRootDat()) > 0) { /* Rotate left. */ ((BiTree)root).setRightSubTree(child.getLeftSubTree()); child.setLeftSubTree((BiTree)root); root = child; child = ((BiTree)root).getRightSubTree(); } return (child.execute(new IVisitor() { public Object emptyCase(BiTree child, Object root) { return (root); } public Object nonEmptyCase(BiTree child, Object root) { helper.setLeftSubTreeMax((BiTree)root); return (child.execute(Outer.this, root)); } }, root)); } }, root)); } else return (root); } } BiTree root = (BiTree)host.execute(new Outer(), null); helper.setLeftSubTreeMax(root.getLeftSubTree()); helper.setRightSubTreeMin(root.getRightSubTree()); root.setLeftSubTree(helper.getLeftSubTree()); root.setRightSubTree(helper.getRightSubTree()); return (root); } }