package tree; import exceptions.*; import position.NodePositionList; import position.Position; import position.PositionList; import java.util.Iterator; /** * Created with xgiovio.macbookair. * User: xgiovio * Date: 07/04/14 * Time: 15:45 */ public class LinkedTree implements Tree { protected TreePosition root = null; protected int size = 0; public int size() { return size; } public boolean isEmpty() { return (size == 0); } public Iterable> positions() { PositionList> positions = new NodePositionList>(); if(size != 0) preorderPositions(root(), positions); return positions; } public E replace(Position v, E o) throws InvalidPositionException { TreePosition vv = checkPosition(v); E temp = v.element(); vv.setElement(o); return temp; } public Position root() throws EmptyTreeException { if (root == null) throw new EmptyTreeException("The tree is empty"); return root; } public Position parent(Position v) throws InvalidPositionException, BoundaryViolationException { TreePosition vv = checkPosition(v); Position parentPos = vv.getParent(); if (parentPos == null) throw new BoundaryViolationException("No parent"); return parentPos; } public Iterable> children(Position v) throws InvalidPositionException { TreePosition vv = checkPosition(v); if (isExternal(v)) throw new InvalidPositionException("External nodes have no children"); return vv.getChildren(); } public boolean isInternal(Position v) throws InvalidPositionException { return !isExternal(v); } public boolean isExternal(Position v) throws InvalidPositionException { TreePosition vv = checkPosition(v); return vv.getChildren().isEmpty(); } public boolean isRoot(Position v) throws InvalidPositionException { checkPosition(v); return (v == root()); } public Iterator iterator() { Iterable> positions = positions(); PositionList elements = new NodePositionList(); for (Position pos: positions) elements.addLast(pos.element()); return elements.iterator(); } ////////////////////////// help methods protected void preorderPositions(Position v, PositionList> pos) throws InvalidPositionException { TreePosition a = checkPosition(v); pos.addLast(a); for (Position w : a.getChildren()) preorderPositions(w, pos); } protected void postorderPositions(Position v, PositionList> pos) throws InvalidPositionException { TreePosition a = checkPosition(v); for (Position w : a.getChildren()) postorderPositions(w, pos); pos.addLast(a); } protected TreePosition checkPosition(Position v) throws InvalidPositionException { if (v == null || !(v instanceof TreePosition) || isEmpty() ) throw new InvalidPositionException("The position is invalid"); return (TreePosition) v; } public Position addRoot(E e) throws NonEmptyTreeException { if(!isEmpty()) throw new NonEmptyTreeException("Tree already has a root"); size = 1; root = createNode(e,null,null); return root; } public void swapElements(Position v, Position w) throws InvalidPositionException { TreePosition vv = checkPosition(v); TreePosition ww = checkPosition(w); E temp = w.element(); ww.setElement(v.element()); vv.setElement(temp); } protected TreePosition createNode(E element, TreePosition parent, PositionList> children) { return new TreeNode(element,parent,children); } public E removeRoot() throws EmptyTreeException, UndeletableNodeException { if (isEmpty()) throw new EmptyTreeException(); if (size() > 1) throw new UndeletableNodeException(); E to_return = root().element(); root = null; size = 0; return to_return; } public E removeExternalChild(Position v) throws UndeletableNodeException,InvalidPositionException{ TreePosition a = checkPosition(v); if (isExternal(a)) throw new InvalidPositionException(); PositionList> c = a.getChildren(); if (isInternal(c.first().element())) throw new UndeletableNodeException(); E to_return = (c.remove(c.first())).element(); size--; return to_return; } public Position addChild (E e , Position v) throws InvalidPositionException { TreePosition a = checkPosition(v); a.getChildren().addLast(createNode(e,a,null)); size++; return a.getChildren().last().element(); } public E remove (Position v) { TreePosition a = checkPosition(v); if (isInternal(a)) throw new InvalidPositionException(); if (size() == 1) return removeRoot(); PositionList> list = a.getParent().getChildren(); Iterable>> it = list.positions(); for (Position> w : it){ if (w.element() == v){ size--; return (list.remove(w)).element(); } } return null; } @Override public String toString() { String to_return = ""; to_return = to_return + "["; if (size() == 0 ) return to_return+= "]"; NodePositionList> t = new NodePositionList>(); postorderPositions(root(),t); for (Position w :t){ to_return+=w.element() + ","; } to_return = to_return.substring(0, to_return.length()-1); return to_return+= "]"; } }