package cmj.datastructure.list; public class LinkedList implements List { private Node head;// 头结点 private Node current;// 尾结点 private int size; public LinkedList() { // 头指针和尾指针都指向头结点 head = new Node(null, null); current = head; } /** * 添加元素 * * @param o——用于添加的元素 */ public void add(Object o) { Node node = new Node(o, null);// 新建一个结点 current.next = node;// 尾指针指向它 current = current.next;// 尾指针指向最后一个元素 size++; } /** * 在第index个位置插入元素 * * @param index——要插入的位置 * @param o——用于插入的对象 */ public void add(int index, Object o) { Node node = new Node(o, null);// 新建一个结点 if (index == 0) { addFirst(o); } else { Node curr = (Node) this.get(index - 1);// 获得前一个结点 Node behind = (Node) this.get(index);// 获得后一个结点 // 在这两个结点之间插入新的元素,修改引用指向 curr.next = node; node.next = behind; size++; } } /** * 随机访问index位置上的元素 * * @param index——元素的位置 * @return——对应的元素 */ public Object get(int index) { RangeCheck(index);// 检查索引是否越界 Node curr = head;// 得到头结点的引用 // 从头结点开始遍历到第index个元素 for (int i = 0; i <= index; i++) curr = curr.next; return curr; } /** * 删除第index个位置上的元素 * * @param index * @return */ public Object remove(int index) { RangeCheck(index);// 检查索引是否越界 if (0 == index) { return removeFirst(); } else { Node toRemove = (Node) this.get(index);// 获得要删除的结点 Node preRemove = (Node) this.get(index - 1);// 获得前一个结点 preRemove.next = toRemove.next;// 将前一个结点指向要删除的结点的下一个结点 size--; return toRemove; } } /** * 获取元素的大小 * * @return */ public int size() { return size; } /** * 在链表头部增加元素 * * @param o——要增加的元素 */ public void addFirst(Object o) { Node node = new Node(o, null);// 新建一个结点 node.next = head.next;// 结点指向第一个元素 head.next = node;// 将头结点指向它 size++; } /** * 在链表末尾添加元素 * * @param o——要添加的元素 */ public void addLast(Object o) { Node node = new Node(o, null);// 新建一个结点 current.next.next = node;// 尾结点的next指向新建的结点 current.next = node;// 尾结点引用指向向新结点 size++; } /** * 移除第一个元素 * * @return——移除元素 */ public Object removeFirst() { Node curr = head.next;// 新建一个引用记录第一个结点 head.next = curr.next;// 头指针移动到原第二个元素上 size--; return curr; } /** * 移除最后一个元素 * * @return——移除元素 */ public Object removeLast() { Node remove = current.next; Node pre = (Node) this.get(size - 2);// 获得倒数第二个结点 current.next = pre; pre.next = null; size--; return remove; } /** * 就是检查一下是不是超出数组界限了,超出了就抛出IndexOutBoundsException异常。 * * @param index要用于检查的索引 */ private void RangeCheck(int index) { if (index > size || index < 0) throw new IndexOutOfBoundsException("Index: " + index + " 超出访问范围"); } /** * 重写toString()方法 */ @Override public String toString() { String linkedlist = "["; Node visit = head; while (visit.next != null) { visit = visit.next; if (visit.next == null) { linkedlist += visit.data.toString() + "]"; } else { linkedlist += visit.data.toString() + "--->"; } } return linkedlist; } /** * 结点内部类,主要要声明为static的 * * @author think * */ private static class Node { Object data; Node next; public Node(Object data, Node next) { this.data = data; this.next = next; } } public static void main(String[] args) { LinkedList list = new LinkedList(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); System.out.println(list); System.out.println(((Node) list.get(3)).data); list.add(4, "4"); System.out.println(list); list.add(0, "0"); System.out.println(list); list.addLast("last"); System.out.println(list); System.out.println("Removed:" + ((Node) list.remove(1)).data); System.out.println(list); System.out.println("Removed:" + ((Node) list.removeFirst()).data); System.out.println(list); System.out.println("Removed:" + ((Node) list.removeLast()).data); System.out.println(list); } }