一、介绍
本人熟悉的语言是java,所以使用的算法代码都会是java代码。
链表是一个Object一个Object,通过他们之间reference,连接起来的数据结构,就像鸭子排队一样,一个跟着一个走。
形成链表数据结构,就需要用代码定义一个Object,还有Object包含一个reference。
Class Node<T> { // 作为链表的Object
private T val; // 节点的值
private Node<T> next; // 作为下一个节点的联系reference
Node<T>(T val, Node<T> next){
this.val = val;
this.next = next;
}
}
上面定义的是一个单向的链表,就是只有next reference联系下一个节点,如果双向链表就在Node中加一个成员变量private Node<T> pre; 作为previous reference联系前一个节点;
链表作为一种数据结构,会涉及的内存操作就是增删查改,如果要设计LinkedList,可以先阅读java源码中的java.util.LinkedList一些代码。
二、Java-1.8中的LinkedList
(1)成员变量
Java中的LinkedList成员变量是屈指可数的
transient int size = 0; // 记录LinkedList的长度
transient Node<E> first; // LinkedList第一个节点
transient Node<E> last; // LinkedList最后一个节点
// 是属于父类AbstraceList的成员变量,是给迭代器以及Java8新特性Spliterator用的
protected transient int modCount = 0;
使用的Node为
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;
}
}
很明显,Java8的链表是一个双向链表数据结构,双向链表会有一个链表环的问题,如果有链表环(cycle),用迭代器或者遍历双向链表会一直在环(cycle)那里循环遍历,解决方法之后可以有。
(2)增加(add)
A、链表前增加,链表后增加
public void addFirst(E e) {
linkFirst(e);
}
public void addLast(E e) {
linkLast(e);
}
private void linkFirst(E e) {
final Node<E> f = first; // 暂存第一个元素f
final Node<E> newNode = new Node<>(null, e, f); // 根据值new Node
first = newNode;