1. 俩表的概念
链表的概念,链表是由一些列的非连续的节点组成的存储结构,简单分下类的话,链表又分为单向链表和双向链表,而单向/双向链表又可以分为循环链表和非循环链表,下面简单就这四种链表进行简单的说明。
- 单向链表是前面节点只指向后面节点,后面节点不指向前面节点,节点中只有一个成员存储下一个节点位置。
- 双向链表是每个节点都有两个存储下一个和上一个节点位置的成员,链表可以上下游动。
- 循环链表是链表的最后一个节点的尾指针指向头节点,头结点的上一个节点指针指向尾节点,在单向链表中就表现在尾节点的下一个节点指针指向头结点。
- 非循环链表,就是尾节点的下一个节点指针指向空,双向链表中头结点的上一个节点指针和尾节点的下一个节点指针都是指向空的。
2. 底层存储结构
链表的底层存储实体结构为
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
由源码可知,LinkedList采用的双向链表结构。
链表的成员为
transient int size = 0;
/**
* Pointer to first node.
* Invariant: (first == null && last == null) ||
* (first.prev == null && first.item != null)
*/
transient Node<E> first;
/**
* Pointer to last node.
* Invariant: (first == null && last == null) ||
* (last.next == null && last.item != null)
*/
transient Node<E> last;
3. 添加元素
添加元素主要有两个方法,一个默认添加到链表末尾处,一个可以指定添加到指定的位置处。分别为:
public boolean add(E e) {
linkLast(e);
return true;
}
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
Node<E> node(int index) {
// assert isElementIndex(index);
if (index < (size >> 1)) {
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 linkBefore(E e, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev;
final Node<E> newNode = new Node<>(pred, e, succ);
succ.prev = newNode;
if (pred == null)
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}
2. 删除元素,修改元素
剩下的操作比较简单,就不在赘述。
网友评论