package position; import java.util.Iterator; import exceptions.*; import stack.utility.Node; /** * Realization of a PositionList using a doubly-linked list of nodes. * * @author Michael Goodrich, Natasha Gelfand, Roberto Tamassia, Eric Zamore */ //Copyright (c) 2003 Brown University, Providence, RI //Additional modifications and methods by xgiovio public class NodePositionList implements PositionList { protected int numElts; // Number of elements in the list protected DNode header, trailer; // Special sentinels public NodePositionList() { numElts = 0; header = new DNode(null, null, null); // create header trailer = new DNode(header, null, null); // create trailer header.setNext(trailer); // make header and trailer point to each other } protected DNode checkPosition(Position p) throws InvalidPositionException { if (p == null) throw new InvalidPositionException ("Null position passed to NodeList"); if (p == header) throw new InvalidPositionException ("The header node is not a valid position"); if (p == trailer) throw new InvalidPositionException ("The trailer node is not a valid position"); try { DNode temp = (DNode) p; if ((temp.getPrev() == null) || (temp.getNext() == null)) throw new InvalidPositionException ("Position does not belong to a valid NodeList"); return temp; } catch (ClassCastException e) { throw new InvalidPositionException ("Position is of wrong type for this list"); } } public int size() { return numElts; } public boolean isEmpty() { return (numElts == 0); } public Position first() throws EmptyListException { if (isEmpty()) throw new EmptyListException("List is empty"); return header.getNext(); } public Position last() throws EmptyListException { if (isEmpty()) throw new EmptyListException("List is empty"); return trailer.getPrev(); } public Position prev(Position p) throws InvalidPositionException, BoundaryViolationException { DNode v = checkPosition(p); DNode prev = v.getPrev(); if (prev == header) throw new BoundaryViolationException ("Cannot advance past the beginning of the list"); return prev; } public Position next(Position p) throws InvalidPositionException, BoundaryViolationException { DNode v = checkPosition(p); DNode next = v.getNext(); if (next == trailer) throw new BoundaryViolationException ("Cannot advance past the end of the list"); return next; } public void addBefore(Position p, E element) throws InvalidPositionException { DNode v = checkPosition(p); numElts++; DNode newNode = new DNode(v.getPrev(), v, element); v.getPrev().setNext(newNode); v.setPrev(newNode); } public void addAfter(Position p, E element) throws InvalidPositionException { DNode v = checkPosition(p); numElts++; DNode newNode = new DNode(v, v.getNext(), element); v.getNext().setPrev(newNode); v.setNext(newNode); } public void addFirst(E element) { numElts++; DNode newNode = new DNode(header, header.getNext(), element); header.getNext().setPrev(newNode); header.setNext(newNode); } public void addLast(E element) { numElts++; DNode oldLast = trailer.getPrev(); DNode newNode = new DNode(oldLast, trailer, element); oldLast.setNext(newNode); trailer.setPrev(newNode); } public E remove(Position p) throws InvalidPositionException { DNode v = checkPosition(p); numElts--; DNode vPrev = v.getPrev(); DNode vNext = v.getNext(); vPrev.setNext(vNext); vNext.setPrev(vPrev); E vElem = v.element(); v.setNext(null); v.setPrev(null); return vElem; } public E set(Position p, E element) throws InvalidPositionException { DNode v = checkPosition(p); E oldElt = v.element(); v.setElement(element); return oldElt; } public boolean isFirst(Position p) throws InvalidPositionException { DNode v = checkPosition(p); return v.getPrev() == header; } public boolean isLast(Position p) throws InvalidPositionException { DNode v = checkPosition(p); return v.getNext() == trailer; } public void swapElements(Position a, Position b) throws InvalidPositionException { DNode pA = checkPosition(a); DNode pB = checkPosition(b); E temp = pA.element(); pA.setElement(pB.element()); pB.setElement(temp); } @Override public String toString() { String to_return = ""; to_return = to_return + "["; for ( DNode temp = header.getNext(); temp != trailer ; temp = temp.getNext()){ if ( temp.getNext() == trailer){ to_return+=(temp.element().toString()); }else{ to_return+=(temp.element().toString() + ","); } } to_return = to_return + "]"; return to_return; } public void reverse(){ if (size() > 1){ E temp = remove(last()); reverse(); addFirst(temp); } } }