package io.github.vxzh; /** * Created by vxzh on 23/02/2017. */ public class LinkedList implements List { private int size = 0; private Node head; private Node tail; public int size() { return size; } public boolean isEmpty() { return size == 0; } private void linkLast(Object o) { Node node = tail; Node newNode = new Node(tail, o, null); tail = newNode; if (node == null) head = newNode; else node.next = newNode; size++; } private void linkBefore(Object o, Node node) { Node prev = node.prev; Node newNode = new Node(prev, o, node); node.prev = newNode; if (prev == null) head = newNode; else prev.next = newNode; size++; } public boolean add(Object o) { linkLast(o); return true; } public boolean add(int index, Object o) { if (index > size || index < 0) throw new RuntimeException("IndexOutOfBoundsException"); if (index == size) linkLast(o); else linkBefore(o, node(index)); return true; } public boolean remove(Object o) { if (o == null) { return false; } else { for (Node x = head; x != null; x = x.next) { if (o.equals(x.data)) { unlink(x); return true; } } } return false; } public boolean remove(int index) { if (index >= size || index < 0) throw new RuntimeException("IndexOutOfBoundsException"); unlink(node(index)); return true; } public Object get(int index) { if (index >= size || index < 0) throw new RuntimeException("IndexOutOfBoundsException"); return node(index).data; } private void unlink(Node x) { Node prev = x.prev; Node next = x.next; if (prev == null) { head = next; } else { prev.next = next; x.prev = null; } if (next == null) { tail = prev; } else { next.prev = prev; x.next = null; } x.data = null; size--; } private Node node(int index) { if (index < (size >> 1)) { Node x = head; for (int i = 0; i < index; i++) x = x.next; return x; } else { Node x = tail; for (int i = size - 1; i > index; i--) x = x.prev; return x; } } private static class Node { Object data; Node prev; Node next; Node(Node prev, Object element, Node next) { this.data = element; this.next = next; this.prev = prev; } } }