LinkedList
总结
(1)LinkedList是一个以双链表实现的List;
(2)LinkedList还是一个双端队列,具有队列、双端队列、栈的特性;
(3)LinkedList在队列首尾添加、删除元素非常高效,时间复杂度为O(1);
(4)LinkedList在中间添加、删除元素比较低效,时间复杂度为O(n);
(5)LinkedList不支持随机访问,所以访问非队列首尾的元素比较低效;
(6)LinkedList在功能上等于ArrayList + ArrayDeque;
主要元素
transient int size; // 元素个数
transient LinkedList.Node<E> first; // 链表首节点
transient LinkedList.Node<E> last; // 链表尾节点
构造方法
public LinkedList() {
this.size = 0;
}
public LinkedList(Collection<? extends E> c) {
this();
this.addAll(c);
}
添加元素
// 从队列首添加元素
private void linkFirst(E e) {
LinkedList.Node<E> f = this.first;
LinkedList.Node<E> newNode = new LinkedList.Node((LinkedList.Node)null, e, f);
this.first = newNode; // 对手元素换为新节点
if (f == null) {
this.last = newNode;
} else {
f.prev = newNode; // 原列表与新节点连接上
}
++this.size;
++this.modCount;
}
// 从队列尾添加元素
void linkLast(E e) {
LinkedList.Node<E> l = this.last;
LinkedList.Node<E> newNode = new LinkedList.Node(l, e, (LinkedList.Node)null);
this.last = newNode;
if (l == null) {
this.first = newNode;
} else {
l.next = newNode;
}
++this.size;
++this.modCount;
}
public void addFirst(E e) {
this.linkFirst(e);
}
public void addLast(E e) {
this.linkLast(e);
}
// 指定位置添加元素
public void add(int index, E element) {
this.checkPositionIndex(index);
if (index == this.size) {
// 如果index是在队列尾节点之后的一个位置,把新节点直接添加到尾节点之后
this.linkLast(element);
} else {
// 调用linkBefore()方法在中间添加节点
this.linkBefore(element, this.node(index));
}
}
LinkedList.Node<E> node(int index) {
LinkedList.Node x;
int i;
//因为是双链表,所以根据index是在前半段还是后半段决定从前遍历还是从后遍历,
//这样index在后半段的时候可以少遍历一半的元素
if (index < this.size >> 1) {
x = this.first;
for(i = 0; i < index; ++i) {
x = x.next;
}
return x;
} else {
x = this.last;
for(i = this.size - 1; i > index; --i) {
x = x.prev;
}
return x;
}
void linkBefore(E e, LinkedList.Node<E> succ) {
LinkedList.Node<E> pred = succ.prev;
// 在其前置节点和后继节点之间创建一个新节点
LinkedList.Node<E> newNode = new LinkedList.Node(pred, e, succ);
succ.prev = newNode;
if (pred == null) {
this.first = newNode;
} else {
pred.next = newNode;
}
++this.size;
++this.modCount;
}
删除元素
private E unlinkFirst(LinkedList.Node<E> f) {
E element = f.item;
LinkedList.Node<E> next = f.next;
// 添加首节点的内容为null,协助GC
f.item = null;
f.next = null;
this.first = next;
if (next == null) {
this.last = null;
} else {
next.prev = null;
}
--this.size;
++this.modCount;
return element;
}
private E unlinkLast(LinkedList.Node<E> l) {
E element = l.item;
LinkedList.Node<E> prev = l.prev;
l.item = null;
l.prev = null;
this.last = prev;
if (prev == null) {
this.first = null;
} else {
prev.next = null;
}
--this.size;
++this.modCount;
return element;
}
E unlink(LinkedList.Node<E> x) {
E element = x.item;
LinkedList.Node<E> next = x.next;
LinkedList.Node<E> prev = x.prev;
if (prev == null) {
this.first = next;
} else {
prev.next = next;
x.prev = null;
}
if (next == null) {
this.last = prev;
} else {
next.prev = prev;
x.next = null;
}
x.item = null;
--this.size;
++this.modCount;
return element;
}