链表介绍
- 链表是一种物理存储单上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链次序实现的。
- 链表由一系列节点(链表中的每一个元素称为节点)组成,节点可以在运行时动态生成。每个节点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
- 双链表是链表的一种,由节点组成,每个数据点中都有两个指针,分别指向直接后继和直接前驱。
构造方法
public LinkedList() {}
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
插入方法
public boolean add(E e) {
linkLast(e);
return true;
}
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
//链表尾部插入元素element
linkLast(element);
else
//链表index对应位置 插入元素element
linkBefore(element, node(index));// node(index) 原index位的节点元素;element为要插入节点
}
void linkLast(E e) {
final Node<E> l = last;
// new Node<>(l(前继节点),e(新建节点),null(后继节点)
final Node<E> newNode = new Node<>(l, e, null);
//令新结点为尾节点
last = newNode;
if (l == null)
first = newNode;
else
//设置原结点的后继结点是newNode
l.next = newNode;
size++;
modCount++;
}
void linkBefore(E e, Node<E> succ) {
//原index的前继节点pred
final Node<E> pred = succ.prev;
// newNode = pred <-- e -->succ
final Node<E> newNode = new Node<>(pred, e, succ);
//修改原succ节点的前继节点,改为newNode
succ.prev = newNode;
if (pred == null)
first = newNode;
else
//修改pred节点的指针,指向newNode节点
pred.next = newNode;
size++;
modCount++;
}
删除操作
public E remove() {
return removeFirst();
}
public boolean remove(Object o) {
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null) {
unlink(x);
return true;
}
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item)) {
unlink(x);
return true;
}
}
}
return false;
}
Node<E> node(int index) {
// assert isElementIndex(index);
//如果index小于(元素size/2)
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;
}
}
E unlink(Node<E> x) {
// x 为要删除的节点
final E element = x.item;
final Node<E> next = x.next;
final Node<E> prev = x.prev;
//删除节点的前继节点等于null
if (prev == null) {
//头部指向x删除节点的后继节点
first = next;
} else {
//删除元素的前继节点 -->删除元素的后继节点
prev.next = next;
x.prev = null;
}
//(prev) <-x->(next)
if (next == null) {
//尾部指向删除节点的prev
last = prev;
} else {
//(prev) <--(next)
// x--> (next)null
//删除节点的后继节点,指向删除节点的前继节点
next.prev = prev;
x.next = null;
}
//删除X节点
x.item = null;
size--;
modCount++;
return element;
}