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[0]; } 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[0]; } public Object nonEmptyCase(BiTree child, Object... root) { if (((Comparable)input).compareTo(child.getRootDat()) < 0) { /* Rotate right. */ ((BiTree)root[0]).setLeftSubTree(child.getRightSubTree()); child.setRightSubTree((BiTree)root[0]); root[0] = child; child = ((BiTree)root[0]).getLeftSubTree(); } return child.execute(new IVisitor() { public Object emptyCase(BiTree child, Object... root) { return (root[0]); } public Object nonEmptyCase(BiTree child, Object... root) { helper.setRightSubTreeMin((BiTree)root[0]); return (child.execute(Outer.this, root[0])); } }, root[0]); } }, 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[0]); } public Object nonEmptyCase(BiTree child, Object... root) { if (((Comparable)input[0]).compareTo(child.getRootDat()) > 0) { /* Rotate left. */ ((BiTree)root[0]).setRightSubTree(child.getLeftSubTree()); child.setLeftSubTree((BiTree)root[0]); root[0] = child; child = ((BiTree)root[0]).getRightSubTree(); } return (child.execute(new IVisitor() { public Object emptyCase(BiTree child, Object... root) { return (root[0]); } public Object nonEmptyCase(BiTree child, Object... root) { helper.setLeftSubTreeMax((BiTree)root[0]); return (child.execute(Outer.this, root[0])); } }, root[0]); } }, root)); } else return root; } } BiTree root = (BiTree)host.execute(new Outer()); helper.setLeftSubTreeMax(root.getLeftSubTree()); helper.setRightSubTreeMin(root.getRightSubTree()); root.setLeftSubTree(helper.getLeftSubTree()); root.setRightSubTree(helper.getRightSubTree()); return root; } }