package demo;import java.util.Collection;public class MyLinkedList<E> { // 属性 // 构造方法 public MyLinkedList() { } public MyLinkedList(Collection<? extends E> c) { this(); addAll(c); } // 构建双向链表,首先要构建节点 // 建立成员内部类节点, private static class Node<E> { E item; // 存储数据 Node<E> next;// 下一个节点 Node<E> prev; // 前一个节点 public Node(Node<E> next, E item, Node<E> prev) { this.item = item; this.next = next; this.prev = prev; } } // 一个数组域存放数组,一个prev指向前一个节点的next 一个next指向下一个节点的prev. // 第一个节点 private Node<E> first; // 最后一个节点 private Node<E> last; // 数组个数 private int size; // 将指定元素追加到此列表的末尾 public boolean add(E e) { addLast(e); return true; } // 将节点连接到此列表的末尾 void addLast(E e) { Node<E> l = last; // 首先找到最后一个元素 Node<E> node = new Node<E>(null, e, l);// 根据传入的e创建一个新的节点next指向null // item存传入的e prev指向l; last = node; // 将刚刚新创建的节点node变为最后一个节点 if (l == null) { // 如果最后一个节点null first = node; // 第一个节点就为node } else { l.next = node; // 将前一个节点的next指向下一个节点 } size++; // size+1 } public void addfirst(E e) { linkfirst(e); } // 在此列表中的指定位置插入指定的元素 public void add(int index, E e) { checkRange(index);// 首先判断范围 if (index == size) { // 如果插入的在最后一个就调用插入最后一个的方法 addLast(e); } else { // 否则取到index位置对应的node元素,然后替换 Node<E> l = index(index); addBeforeNode(e, l); } } // 在指定元素前插入元素 private void addBeforeNode(E e, Node<E> l) { Node<E> preNode = l.prev; Node<E> newnode = new Node<>(l, e, preNode); if (preNode == null) { first = newnode; } else { preNode.next = newnode; } l.prev = newnode; size++; } // 查找index出的元素 private Node<E> index(int index) {// 采用二分法查找 if (index < (size / 2)) { // 首先判断index在前一半还是后一半的范围,然后找到index出的元素 Node<E> x = first; for (int i = 0; i < index; i++) x = x.next; return x; } else { Node<E> x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; } } void linkfirst(E e) { Node<E> l = first; // 首先找到第一个一个元素 Node<E> node = new Node<E>(l, e, null);// 根据传入的e创建一个新的节点next指向null // item存传入的e prev指向l; first = node; // 将刚刚新创建的节点node变为最后一个节点 if (l == null) { // 如果第一个节点null first = node; // 第一个节点就为node } else { l.prev = node; // 将前一个节点的next指向下一个节点 } size++; // size+1 } // 删除所有的元素 public void clear() { for (Node<E> x = first; x != null;) { Node<E> next = x.next; x.item = null; x.prev = null; x.next = null; x = next; } first = last = null; size = 0; } // 判断是否越界 private void checkRange(int index) { if (index < 0 && index > size) throw new IndexOutOfBoundsException("越界了"); } // 返回列表中指定位置的元素 public E get(int index) { checkRange(index); return index(index).item; } // private void addAll(Collection<? extends E> c) { // TODO Auto-generated method stub } // 返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1。 public int indexOf(Object o) { Node<E> n = first; int c = 0; while (n != null) { if (o != null) { if (o.equals(n.item)) return c; } else { if (n.item == null) { return c; } } c++; n = n.next; } return -1; } //删除指定节点 public E remove (int index){ checkRange(index); return unlink(index); } //删除指定对象 public boolean remove(Object o){ int index = indexOf(o); if(index<0){ return false; } unlink(index); return true; } //删除index对应的节点的连接 private E unlink(int index){ Node<E> l = index(index); E item = l.item; Node<E> preNode = l.prev; Node<E> nextNode = l.next; if(preNode==null){ first = nextNode; }else{ preNode.next=nextNode; l.next=null; } if(nextNode==null){ last = preNode; }else{ nextNode.prev = preNode; l.prev=null; } size--; l.item=null; return item; }}
LinkedList是基于双向链表实现的,
LinkedList和ArrayList的区别:
ArrayList基于数组实现,因此具有数组的特点:有序.元素可重复.插入慢.查找快
LinkedList 基于双向链表实现, 因此具有链表特带你 插入快、 查找慢的特性;