java双向链表
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。
代码实现
public class MyLinkedList<E> {
int size = 0;
Node<E> first;
Node<E> last;
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
public Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
// 头部新增
void linkFirst(E e) {
final Node<E> f = first;
final Node<E> newNode = new Node<>(null, e, f);
first = newNode;
if (f == null)
last = newNode;
else
f.prev = newNode;
size++;
}
// 尾部新增
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++;
}
// 指定元素前新增
void linkBefore(E e, Node<E> succ) {
final Node<E> prev = succ.prev;
final Node<E> newNode = new Node<>(prev, e, succ);
succ.prev = newNode;
if (prev == null)
first = null;
else
prev.next = succ;
size++;
}
// 头部删除
E unLinkFirst(Node<E> f) {
final E element = f.item;
final Node<E> next = f.next;
f.item = null;
f.next = null;
first = next;
if (next == null)
first = null;
else
next.prev = null;
size--;
return element;
}
// 尾部删除
E unLinkLast(Node<E> l) {
final E element = l.item;
final Node<E> prev = l.prev;
l.item = null;
l.prev = null;
last = prev;
if (prev == null)
last = null;
else
prev.next = null;
size--;
return element;
}
// 指定元素删除
E unLink(Node<E> x) {
final E element = x.item;
final Node<E> prev = x.prev;
final Node<E> next = x.next;
if (prev == null)
first = next;
else {
prev.next = next;
x.prev = null;
}
if (next == null)
last = prev;
else {
next.prev = prev;
x.next = null;
}
x.item = null;
size--;
return element;
}
// 获取链表第一个元素
public E getFirst() {
final Node<E> f = first;
if (f == null) {
throw new NoSuchElementException();
}
return f.item;
}
// 获取链表最后一个元素
public E getLast() {
final Node<E> l = last;
if (l == null)
throw new NoSuchElementException();
return l.item;
}
// 移除链表第一个元素
public E removeFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return unLinkFirst(f);
}
// 移除链表最后一个元素
public E removeLast() {
final Node<E> l = last;
if (l == null)
throw new NoSuchElementException();
return unLinkLast(l);
}
// 在列表的开头插入指定的元素
public void addFirst(E e) {
linkFirst(e);
}
// 将指定的元素追加到列表的末尾
public void addLast(E e) {
linkLast(e);
}
// 判断列表中是否有该元素
public boolean contains(Object o) {
return indexOf(o) != -1;
}
// 返回列表中元素的个数
public int size() {
return size;
}
// 将指定元素追加到链表的末尾
public boolean add(E e) {
linkLast(e);
return true;
}
// 将指定元素移除列表
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;
}
// 从指定位置开始,将指定集合中的全部元素插入到此列表
public boolean addAll(int index, Collection<? extends E> c) {
checkPositionIndex(index);
Object[] arr = c.toArray();
int len = arr.length;
if (len == 0)
return false;
Node<E> prev, succ;
if (index == size) {
succ = null;
prev = last;
} else {
succ = node(index);
prev = succ.prev;
}
for (Object o : arr) {
@SuppressWarnings("unchecked") E e = (E) o;
Node<E> newNode = new Node<>(prev, e, null);
if (prev == null)
first = newNode;
else
prev.next = newNode;
prev = newNode;
}
if (succ == null) {
last = prev;
} else {
prev.next = succ;
succ.prev = prev;
}
size += len;
return true;
}
// 清空链表
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;
}
// 返回位于列表中指定位置的元素
public E get(int index) {
checkPositionIndex(index);
return node(index).item;
}
// 将列表中指定位置的元素替换为指定元素
public E set(int index, E element) {
checkPositionIndex(index);
Node<E> x = node(index);
E oldVal = x.item;
x.item = element;
return oldVal;
}
// 将指定元素插入到列表中的指定位置
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
// 删除位于列表中指定位置的元素
public E remove(int index) {
checkPositionIndex(index);
return unLink(node(index));
}
// 返回列表中指定元素第一次出现的索引,如果列表中不包含该元素,则返回-1
public int indexOf(Object o) {
int index = 0;
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null)
return index;
index++;
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item))
return index;
index++;
}
}
return -1;
}
// 返回列表中指定元素最后一次出现的索引,如果列表中不包含该元素,则返回-1
public int lastIndexOf(Object o) {
int index = size;
if (o == null) {
for (Node<E> x = last; x != null; x = x.prev) {
index--;
if (x.item == null) {
return index;
}
}
} else {
for (Node<E> x = last; x != null; x = x.prev) {
index--;
if (o.equals(x.item)) {
return index;
}
}
}
return -1;
}
// 返回指定元素索引处的Node(非空)
Node<E> node(int 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;
}
}
// 审查索引是否越界
private void checkPositionIndex(int index) {
if (!isPositionIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
// 判断索引是否有效
private boolean isPositionIndex(int index) {
return index >= 0 && index <= size;
}
// 索引越界异常详细信息
private String outOfBoundsMsg(int index) {
return "Index: " + index + ", Size: " + size;
}
// 返回一个数组,按正确的顺序(从第一个元素到最后一个元素)包含这个列表中的所有元素
public Object[] toArray() {
Object[] result = new Object[size];
int i = 0;
for (Node<E> x = first; x != null; x = x.next)
result[i++] = x.item;
return result;
}
}