package org.coding.one; /** * 双链表/双向链表 */ public class LinkedList implements List { private Node first; private Node last; private int size = 0; @Override public void add(Object o) { Node newNode = new Node(o, null); if(this.last != null) { this.last.next = newNode; this.last = newNode; } else { this.first = newNode; this.last = newNode; } this.size++; } @Override public void add(int index, Object o) { checkIndex(index); if(index == 0) { //first Node newNode = new Node(o, this.first); this.first = newNode; if(this.last == null) { //通过该方法放入第一个元素时 this.last = newNode; } this.size++; } else if (index == this.size) { //last add(o); } else { Node preNode = findNode(index - 1); Node nextNode = preNode.next; Node newNode = new Node(o, nextNode); preNode.next = newNode; this.size++; } } /** * 通过角标获取对应的 Node 对象 * @param index (0 <= index < size) * @return */ private Node findNode(int index) { Node node = this.first; for(int i = 1; i <= index ; i++) { node = node.next; } return node; } /** * 0 <= index <= size * @param index */ private void checkIndex(int index) { if(index < 0 || index > this.size) { throw new IndexOutOfBoundsException("Index: "+index+", Size: "+ this.size); } } @Override public Object get(int index) { checkRangeIndex(index); return findNode(index).data; } /** * 0 <= index < size * @param index */ private void checkRangeIndex(int index) { if(index < 0 || index > this.size - 1) { throw new IndexOutOfBoundsException("Index: "+index+", Size: "+ this.size); } } @Override public Object remove(int index) { checkRangeIndex(index); Node oldNode = null; if(index == 0) { oldNode = this.first; this.first = oldNode.next; } else { Node preNode = findNode(index - 1); oldNode = preNode.next; preNode.next = oldNode.next; } oldNode.next = null; this.size--; return oldNode.data; } @Override public int size() { return this.size; } @Override public boolean isEmpty() { return this.size == 0; } public void addFirst(Object o){ add(0, o); } public void addLast(Object o){ add(this.size, o); } public Object removeFirst(){ return remove(0); } public Object removeLast(){ return remove(size - 1); } private static class Node { private Object data; private Node next; public Node(Object data, Node next) { super(); this.data = data; this.next = next; } } }