public class LinkedPositionalList<E> implements PositionalList<E>, Iterable<E> {
private static class Node<E> implements Position<E> {
private E element;
private Node<E> next;
private Node<E> prev;
public Node(E e, Node<E> prevNode, Node<E> nextNode) {
element = e;
prev = prevNode;
next = nextNode;
}
public Node<E> getNext() { return next; }
public Node<E> getPrev() { return prev; }
public void setNext(Node<E> nextNode) { next = nextNode; }
public void setPrev(Node<E> prevNode) { prev = prevNode; }
public void setElement(E e) { element = e; }
@Override
public E getElement() throws IllegalStateException {
if (next == null) throw new IllegalStateException("Position no longer valid");
return element;
}
}
private Node<E> headSentinel;
private Node<E> tailSentinel;
private int size;
public LinkedPositionalList() {
headSentinel = new Node<>(null, null, null);
tailSentinel = new Node<>(null, headSentinel, null);
headSentinel.setNext(tailSentinel);
}
@Override
public int size() { return size; }
@Override
public boolean isEmpty() { return (size == 0); }
@Override
public Position<E> first() {
if (isEmpty()) return null;
return headSentinel.getNext();
}
@Override
public Position<E> last() {
if (isEmpty()) return null;
return tailSentinel.getPrev();
}
@Override
public Position<E> before(Position<E> p) throws IllegalArgumentException {
if (!(p instanceof Node)) throw new IllegalArgumentException("Invalid p");
if (((Node<E>) p).getNext() == null) throw new IllegalArgumentException("Position no longer valid");
return ((Node<E>) p).getPrev();
}
@Override
public Position<E> after(Position<E> p) throws IllegalArgumentException {
if (!(p instanceof Node)) throw new IllegalArgumentException("Invalid p");
if (((Node<E>) p).getNext() == null) throw new IllegalArgumentException("Position no longer valid");
return ((Node<E>) p).getNext();
}
@Override
public Position<E> addFirst(E e) {
Node<E> addNode = new Node<>(e, headSentinel,headSentinel.getNext());
headSentinel.getNext().setPrev(addNode);
headSentinel.setNext(addNode);
size++;
return addNode;
}
@Override
public Position<E> addLast(E e) {
Node<E> addNode = new Node<>(e, tailSentinel.getPrev(),tailSentinel);
tailSentinel.getPrev().setNext(addNode);
tailSentinel.setPrev(addNode);
size++;
return addNode;
}
@Override
public Position<E> addBefore(Position<E> p, E e) throws IllegalArgumentException {
if (!(p instanceof Node)) throw new IllegalArgumentException("Invalid p");
if (((Node<E>) p).getNext() == null) throw new IllegalArgumentException("Position no longer valid");
Node<E> temp = (Node<E>) p;
Node<E> addNode = new Node<>(e, temp.getPrev(), temp);
temp.getPrev().setNext(addNode);
temp.setPrev(addNode);
size++;
return addNode;
}
@Override
public Position<E> addAfter(Position<E> p, E e) throws IllegalArgumentException {
if (!(p instanceof Node)) throw new IllegalArgumentException("Invalid p");
if (((Node<E>) p).getNext() == null) throw new IllegalArgumentException("Position no longer valid");
Node<E> temp = (Node<E>) p;
Node<E> addNode = new Node<>(e, temp, temp.getNext());
temp.getNext().setPrev(addNode);
temp.setNext(addNode);
size++;
return addNode;
}
@Override
public E set(Position<E> p, E e) throws IllegalArgumentException {
if (!(p instanceof Node)) throw new IllegalArgumentException("Invalid p");
if (((Node<E>) p).getNext() == null) throw new IllegalArgumentException("Position no longer valid");
Node<E> temp = (Node<E>) p;
temp.setElement(e);
return temp.getElement();
}
@Override
public E remove(Position<E> p) throws IllegalArgumentException {
if (!(p instanceof Node)) throw new IllegalArgumentException("Invalid p");
if (((Node<E>) p).getNext() == null) throw new IllegalArgumentException("Position no longer valid");
Node<E> temp = (Node<E>) p;
temp.getPrev().setNext(temp.getNext());
temp.getNext().setPrev(temp.getPrev());
size--;
E tempElement = temp.getElement();
temp.setPrev(null);
temp.setNext(null);
temp.setElement(null);
return tempElement;
}
@Override
public Iterable<Position<E>> positions() {
java.util.List<Position<E>> snapshot = new java.util.ArrayList<>();
Position<E> current = first();
while (current != null) {
snapshot.add(current);
current = after(current);
}
return snapshot;
}
private class ElementIterator implements Iterator<E> {
private Position<E> cursor = first();
private Position<E> recent = null;
@Override
public boolean hasNext() { return (cursor != null); }
@Override
public E next() throws NoSuchElementException {
if (cursor == null) throw new NoSuchElementException();
E answer = cursor.getElement();
recent = cursor;
cursor = after(recent);
return answer;
}
@Override
public void remove() throws NoSuchElementException{
if (recent == null) throw new NoSuchElementException();
LinkedPositionalList.this.remove(recent);
recent = null;
}
}
@Override
public Iterator<E> iterator() {
return new ElementIterator();
}
}
近期评论