Files
unisa_strutture_dati_2013_2014/position/NodePositionList.java

271 lines
7.3 KiB
Java

package position;
import exceptions.*;
import iterator.ElementIterator;
import position.utility.DNode;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* 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<E> implements PositionList<E> {
protected int numElts; // Number of elements in the list
protected DNode<E> header, trailer; // Special sentinels
public NodePositionList() {
numElts = 0;
header = new DNode<E>(null, null, null); // create header
trailer = new DNode<E>(header, null, null); // create trailer
header.setNext(trailer); // make header and trailer point to each other
}
protected DNode<E> checkPosition(Position<E> 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<E> temp = (DNode<E>) 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<E> first() throws EmptyListException {
if (isEmpty())
throw new EmptyListException("List is empty");
return header.getNext();
}
public Position<E> last()
throws EmptyListException {
if (isEmpty())
throw new EmptyListException("List is empty");
return trailer.getPrev();
}
public Position<E> prev(Position<E> p) throws InvalidPositionException, BoundaryViolationException {
DNode<E> v = checkPosition(p);
DNode<E> prev = v.getPrev();
if (prev == header)
throw new BoundaryViolationException
("Cannot advance past the beginning of the list");
return prev;
}
public Position<E> next(Position<E> p) throws InvalidPositionException, BoundaryViolationException {
DNode<E> v = checkPosition(p);
DNode<E> next = v.getNext();
if (next == trailer)
throw new BoundaryViolationException
("Cannot advance past the end of the list");
return next;
}
public Position<E> addBefore(Position<E> p, E element) throws InvalidPositionException {
DNode<E> v = checkPosition(p);
numElts++;
DNode<E> newNode = new DNode<E>(v.getPrev(), v, element);
v.getPrev().setNext(newNode);
v.setPrev(newNode);
return newNode;
}
public Position<E> addAfter(Position<E> p, E element) throws InvalidPositionException {
DNode<E> v = checkPosition(p);
numElts++;
DNode<E> newNode = new DNode<E>(v, v.getNext(), element);
v.getNext().setPrev(newNode);
v.setNext(newNode);
return newNode;
}
public void addFirst(E element) {
numElts++;
DNode<E> newNode = new DNode<E>(header, header.getNext(), element);
header.getNext().setPrev(newNode);
header.setNext(newNode);
}
public void addLast(E element) {
numElts++;
DNode<E> oldLast = trailer.getPrev();
DNode<E> newNode = new DNode<E>(oldLast, trailer, element);
oldLast.setNext(newNode);
trailer.setPrev(newNode);
}
public E remove(Position<E> p)
throws InvalidPositionException {
DNode<E> v = checkPosition(p);
numElts--;
DNode<E> vPrev = v.getPrev();
DNode<E> 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<E> p, E element)
throws InvalidPositionException {
DNode<E> v = checkPosition(p);
E oldElt = v.element();
v.setElement(element);
return oldElt;
}
public boolean isFirst(Position<E> p)
throws InvalidPositionException {
DNode<E> v = checkPosition(p);
return v.getPrev() == header;
}
public boolean isLast(Position<E> p)
throws InvalidPositionException {
DNode<E> v = checkPosition(p);
return v.getNext() == trailer;
}
public void swapElements(Position<E> a, Position<E> b)
throws InvalidPositionException {
DNode<E> pA = checkPosition(a);
DNode<E> 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<E> 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);
}
}
@Override
// iterator created using specific class for PositionList data structures : ElementIterator
public Iterator<E> iterator() {
return new ElementIterator<E>(this);
}
public Iterator<Position<E>> positions() {
return new MyPositionsIterator(this);
}
class MyPositionsIterator implements Iterator<Position<E>>{
public MyPositionsIterator (NodePositionList<E> structure){
new_structure = new NodePositionList<Position<E>>();
if (structure.size() != 0){
Position<E> temp;
for (temp = structure.first() ; temp!= structure.last() ; temp = structure.next(temp)){
new_structure.addLast(temp);
}
new_structure.addLast(temp);
}
}
@Override
public boolean hasNext() {
if (pos == null){
if (new_structure.size() <= 0){
return false;
} else {
return true;
}
} else {
try {
new_structure.next(pos);
return true;
}
catch (BoundaryViolationException err){
return false;
}
}
}
@Override
public Position<E> next() throws NoSuchElementException {
if (hasNext()){
if (pos == null){
pos = new_structure.first();
}else {
pos = new_structure.next(pos);
}
return pos.element();
} else{
throw new NoSuchElementException();
}
}
@Override
public void remove() {
throw new UnsupportedOperationException ();
}
NodePositionList<Position<E>> new_structure;
Position<Position<E>> pos = null;
}
}