package com.java.xiaoqin.impl; import com.java.xiaoqin.interfaces.IIterator; import com.java.xiaoqin.interfaces.IList; import com.java.xiaoqin.interfaces.IQueue; /** * Created by xiaoqin on 17-2-26. */ public class LinkedListImpl<T> implements IList<T>, IQueue<T> { private Node<T> head; private Node<T> last; private int size = 0; public LinkedListImpl() { } @Override public void add(T t) { if (size == 0) { head = new Node<>(); head.data = t; head.index = size++; last = head; } else { last.right = new Node<>(); last.right.left = last; last = last.right; last.data = t; last.index = size++; } } @Override public void add(int index, T t) { Node<T> node = findNodeByIndex(index); if (node.index == 0) { node.left = new Node<>(); node.left.right = node; node.left.index = 0; node.left.data = t; head = node.left; } else { node.left.right = new Node<>(); node.left.right.index = node.index; node.left.right.right = node; node.left.right.data = t; node.left = node.left.right; } while (node != null) { node.index++; node = node.right; } size++; } private Node<T> findNodeByIndex(int index) { if (index >= size) { throw new ArrayIndexOutOfBoundsException("index:" + index); } Node<T> resultNode = null; Node<T> origin = null; int half = size >> 1; if (index > half) { origin = last; while (origin.index != index) { origin = origin.left; } } else { origin = head; while (origin.index != index) { origin = origin.right; } } return origin; } @Override public T get(int index) { return findNodeByIndex(index).data; } @Override public T remove(int index) { Node<T> node = findNodeByIndex(index); if (null != node.left) { node.left.right = node.right; } else { node.right.left = null; head = node.right; } if (null != node.right) { node.right.left = node.left; while (node.right == null) { node.right.index--; } } else { node.left.right = null; last = node.left; } size--; return node.data; } @Override public int size() { return size; } @Override public void enQueue(T t) { add(t); } @Override public T deQueue() { if (0 >= size) { throw new NullPointerException("remove is null"); } T t = null; Node<T> node = findNodeByIndex(0); if (null != node) { t = node.data; if (null != node.right) { node.right.left = null; Node<T> right = node.right; head = right; while (right != null) { right.index--; right = right.right; } size--; } else { head = last = null; size = 0; } } return t; } @Override public boolean isEmpty() { return size == 0; } @Override public IIterator<T> iterator() { return new LinkedIteratorImpl<>(); } @Override public String toString() { StringBuilder sbToString = new StringBuilder(); Node<T> temp = head; while (null != temp){ sbToString.append(temp.toString()).append("\n"); temp = temp.right; } return sbToString.toString(); } private static class Node<T> { private T data = null; private Node<T> left = null; private Node<T> right = null; private int index = 0; @Override public String toString() { return "Node{" + "data=" + data + ", index=" + index + '}'; } } private class LinkedIteratorImpl<T> implements IIterator<T> { private int index = 0; private Node<T> next; @Override public boolean hasNext() { return index < size; } @Override public T next() { if (0 == index) { next = (Node<T>) head; } if (null == next) { throw new ArrayIndexOutOfBoundsException("next is null"); } Node<T> result = next; next = next.right; index++; return result.data; } } }