Skip to content

LinkedList

About 1702 wordsAbout 6 min

2025-05-03

因为LinkedList实现了List、Deque等接口,暂时先往后放一放,先把List学习了。

底层比较重要的方法有:

  • linkFirst(E e)
  • linkLast(E e)
  • linkBefore(E e, Node<E> succ)
  • unlinkFirst()
  • unlinkLast()

LinkedList底层是通过链条实现的,所以它的特点就是插入、删除效率高,但是查询效率低,因为需要从头遍历查找对应的元素。

public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable{
  	transient int size;
  	transient Node<E> first;  // first节点
  	transient Node<E> last;  // last节点
}

transient修饰的字段将不被序列化,字段的生命周期仅存在于调用者的内存中,而不会被写道磁盘中。

节点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;
    }
}

private void linkFirst(E e)

是私有方法,在first节点之前插入一个节点。

维护fist节点,方便后面通过getFirst方法获取元素。

private 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++;
    modCount++;
}

void linkLast(E e)

在last节点后面添加节点。

维护last节点,后面方便getLast方法直接返回最后一个元素

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++;
}

void linkBefore(E e, Node<E> succ)

在节点succ前面添加元素e

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++;
}

private E unlinkFirst(Node <E> f)

将first指向first.next, f.item = null; f.next = null; first = next;

private E unlinkLast(Node<E> l)

l.item = null; f.prev = null;

public E getFirst()

返回链表第一个节点元素值

public E getFirst() {
    final Node<E> f = first;
    if (f == null)
        throw new NoSuchElementException();
    return f.item;
}

public E getLast()

返回链表最后一个节点元素值

public E getLast() {
    final Node<E> l = last;
    if (l == null)
        throw new NoSuchElementException();
    return l.item;
}

public E removeFirst()

删除第一个节点

public E removeFirst() {
    final Node<E> f = first;
    if (f == null)
        throw new NoSuchElementException();
    return unlinkFirst(f);
}

public E removeLast()

删除最后一个节点

public E removeLast() {
    final Node<E> l = last;
    if (l == null)
        throw new NoSuchElementException();
    return unlinkLast(l);  // 就是把最后一个元素删除掉 
}

public void addFirst(E e)

在列表最前面添加一个元素

public void addFirst(E e) {
    linkFirst(e);
}

public void addLast(E e)

在列表最后添加一个节点

public void addLast(E e) {
    linkLast(e);
}

public boolean contains(Object o)

判断元素是否在列表中,indexOf返回所在的下标,列表不包含元素返回-1

public int size()

public int size() {
    return size;
}

public boolean add(E e)

默认在列表最后添加元素

public boolean add(E e) {
  	// 调用linkLast方法添加元素
    linkLast(e);  
    return true;
}

public boolean remove(Object o)

删除指定元素

public boolean addAll(Collection<?> c)

public void clear()

public E get(int index)

public E get(int index) {
  	// 校验index是否合法, index >= 0 && index < size
    checkElementIndex(index);
    return node(index).item;
}

public E set(int index, E element)

校验index, node(index),因为需要返回oldVal,x.item = element;

public E set(int index, E element) {
    checkElementIndex(index);
    Node<E> x = node(index);
    E oldVal = x.item;
    x.item = element;
    return oldVal;
}

public int indexOf(Object o)

从前往后遍历,返回匹配的一个元素的下标,未匹配返回-1

public int lastIndexOf(Object o)

从后往前匹配,返回匹配的第一个元素的下标,未匹配返回-1

二、Queue Operations

队列相关的操作。

public E peek()

返回队列的第一个元素。

public E peek() {
    final Node<E> f = first;
    return (f == null) ? null : f.item;
}

public E element

返回队列的第一个元素

public E element() {
    return getFirst();
}

public E poll()

返回列表第一个元素后删除

public E poll() {
    final Node<E> f = first;
    return (f == null) ? null : unlinkFirst(f);
}

public E remove()

同poll

public E remove() {
    return removeFirst();
}

public boolean offer(E e)

在队尾添加元素

public boolean offer(E e) {
    return add(e);
}

public boolean offerFirst(E e)

同deque,双端队列,可以在对首添加元素

public boolean offerFirst(E e) {
    addFirst(e);
    return true;
}

public boolean offerLast(E e)

在队尾添加元素

public boolean offerFirst(E e) {
    addFirst(e);
    return true;
}

public E peekFirst()

peekFirst 同 peek

public E peekFirst() {
    final Node<E> f = first;
    return (f == null) ? null : f.item;
 }
public E peekLast() {
    final Node<E> l = last;
    return (l == null) ? null : l.item;
}

public E pollFirst()

pollFirst 同poll

public E pollFirst() {
    final Node<E> f = first;
    return (f == null) ? null : unlinkFirst(f);
}
public E pollLast() {
    final Node<E> l = last;
    return (l == null) ? null : unlinkLast(l);
}

三、Stack Operations

Java堆栈Stack类已经过时了,Java官方推荐使用Deque替代Stack使用。Deque堆栈操作方法为:push, pop, peek

public void push(E e)

在栈顶添加元素

public void push(E e) {
    addFirst(e);
}

public E pop()

弹出栈顶元素

public E pop() {
    return removeFirst();
}

public E peek()

public E peek() {
    final Node<E> f = first;
    return (f == null) ? null : f.item;
}

Changelog

6/3/25, 1:49 AM
View All Changelog
  • d3a6d-Merge branch 'dev1'on

求求了,快滚去学习!!!

求求了求求了,快去学习吧!

【题单】贪心算法

不知道方向的时候,可以多看看书,书会给你指明下一步该干什么,加油!