package com.datastructures.basic; public class LinkedList<E> implements List<E> { private int size = 0; private Node<E> head = new Node<>(); private Node<E> tail = new Node<>(); public LinkedList() { head.next = tail; tail.prev = head; } public void add(E e) { addLast(e); } public void add(int index, E e) { if (index < 0 || index > size) { throw new IndexOutOfBoundsException(Integer.toString(index)); } Node<E> cursor; if (index < size/2) { cursor = head; for (int i = 0, num = index; i < num; ++i) { cursor = cursor.next; } } else { cursor = tail.prev; for (int i = 0, num = size-index; i < num; ++i) { cursor = cursor.prev; } } cursor.next = cursor.next.prev = new Node<E>(e, cursor, cursor.next); ++size; } public E get(int index) { if (index < 0 || index >= size) { throw new IndexOutOfBoundsException(Integer.toString(index)); } Node<E> cursor; if (index < size/2) { cursor = head.next; for (int i = 0; i < index; ++i) { cursor = cursor.next; } } else { cursor = tail.prev; for (int i = 0, num = size-index-1; i < num; ++i) { cursor = cursor.prev; } } return cursor.data; } public E remove(int index) { if (index < 0 || index >= size) { throw new IndexOutOfBoundsException(Integer.toString(index)); } Node<E> cursor; if (index < size/2) { cursor = head.next; for (int i = 0; i < index; ++i) { cursor = cursor.next; } } else { cursor = tail.prev; for (int i = 0, num = size-index-1; i < num; ++i) { cursor = cursor.prev; } } cursor.prev.next = cursor.next; cursor.next.prev = cursor.prev; --size; return cursor.data; } public int size() { return size; } public boolean isEmpty() { return size == 0; } public void addFirst(E e) { add(0, e); } public void addLast(E e) { add(size, e); } public E removeFirst() { return remove(0); } public E removeLast() { return remove(size-1); } public void clear() { while (!isEmpty()) { removeFirst(); } } public boolean contains(E e) { Iterator it = this.iterator(); while (it.hasNext()) { if (it.next() == e) { return true; } } return false; } public E[] toArray() { return null; } public Iterator iterator() { return new LinkedListIterator(); } private static class Node<E> { E data = null; Node<E> prev = null; Node<E> next = null; public Node() { } public Node(E e, Node p, Node n) { data = e; prev = p; next = n; } } private class LinkedListIterator implements Iterator<E> { Node<E> currentNode = head.next; public boolean hasNext() { return currentNode != tail; } public E next() { if (!hasNext()) { throw new java.util.NoSuchElementException(); } E data = currentNode.data; currentNode = currentNode.next; return data; } public void remove() { if (!hasNext()) { throw new java.util.NoSuchElementException(); } Node<E> nextNode = currentNode.next; currentNode.next.prev = currentNode.prev; currentNode.prev.next = currentNode.next; currentNode = nextNode; --size; } } }