LinkedList数据结构链表

LinkedList在Java中是一个实现了ListDeque接口的双向链表。它允许我们在列表的两端添加或删除元素,同时也支持在列表中间插入或移除元素。在分析LinkedList之前,需要理解链表这种数据结构:

  • 链表:链表是一种动态数据结构,由一系列节点组成,每个节点包含数据部分和指向列表中下一个节点的引用。
  • 双向链表:每个节点都有两个链接,一个指向前一个节点,另一个指向后一个节点。

LinkedList 的数据结构

LinkedList中,每个元素都是一个节点,每个节点包含三个部分:存储的数据项、指向前一个节点的引用和指向后一个节点的引用。

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 的核心方法

LinkedList实现了List接口,所以它具有诸如add, remove, get, set等方法,同时也实现了Deque接口,这意味着它也具有offer, poll, push, pop等方法。

源码解析(简化版)

以下是LinkedList中一些关键方法的简化版源码:

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable {
   

    transient int size = 0;
    transient Node<E> first;
    transient Node<E> last;

    public LinkedList() {
   
    }

    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 E remove() {
   
        return unlinkFirst(first);
    }

    private 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)
            last = null;
        else
            next.prev = null;
        size--;
        modCount++;
        return element;
    }

    public E get(int index) {
   
        checkElementIndex(index);
        return node(index).item;
    }

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

    // 省略其他细节实现
}

代码演示

下面是LinkedList的一个简单使用示例:

import java.util.LinkedList;

public class Main {
   
    public static void main(String[] args) {
   
        LinkedList<String> friends = new LinkedList<>();

        // 添加元素
        friends.add("Alice");
        friends.add("Bob");
        friends.add("Charlie");

        // 打印所有元素
        System.out.println("Initial LinkedList: " + friends);

        // 删除第一个元素
        friends.remove();

        // 打印删除元素后的列表
        System.out.println("After removal: " + friends);

        // 获取特定位置的元素
        String friend = friends.get(1);
        System.out.println("Second friend: " + friend);
    }
}

细节分析

使用LinkedList时,有几个细节需要注意:

  • 动态扩展:由于LinkedList是基于节点的,因此它可以动态地添加或删除节点而不需要像数组那样重新分配整个数据结构。
  • 随机访问效率低:获取特定索引的元素时,LinkedList必须从头开始(或从尾开始,取决于哪边更近)遍历节点。因此,随机访问的效率远低于数组。
  • 插入和删除效率高:在任何位置插入或删除元素时,LinkedList只需要改变几个引用,这使得插入和删除操作非常快速。
  • 内存开销:与数组相比,LinkedList的每个元素都需要额外的内存空间来存储前后节点的引用。

通过以上解析,我们可以深入理解LinkedList的工作原理和设计。这有助于开发者在需要适合的数据结构时作出明智的选择。对于需要频繁插入和删除操作的场景,LinkedList可能是一个不错的选择。然而,如果需要快速通过索引访问元素,那么ArrayList可能是更好的选择。

相关推荐

  1. LinkedList数据结构

    2024-02-17 17:04:02       58 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-17 17:04:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-17 17:04:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-02-17 17:04:02       82 阅读
  4. Python语言-面向对象

    2024-02-17 17:04:02       91 阅读

热门阅读

  1. 牛客 数星星 Stars

    2024-02-17 17:04:02       56 阅读
  2. vue实现多个下拉框联动(一)

    2024-02-17 17:04:02       45 阅读
  3. 深度学习与机器学习的关系

    2024-02-17 17:04:02       52 阅读
  4. Qt 说明Q_PROPERTY的作用

    2024-02-17 17:04:02       49 阅读
  5. python无人医疗战车

    2024-02-17 17:04:02       48 阅读
  6. 【C++搜索】DFS:排列与组合

    2024-02-17 17:04:02       54 阅读
  7. 45. 跳跃游戏 II(难度:中等)

    2024-02-17 17:04:02       43 阅读
  8. 617. 合并二叉树

    2024-02-17 17:04:02       57 阅读
  9. 关于管理方法的总结

    2024-02-17 17:04:02       49 阅读