Java中的LinkedList是双链表

在Java中,LinkedList是一种双链表的数据结构。它实现了List接口,并且可以在任意位置进行高效的插入和删除操作。相对于ArrayList,LinkedList的插入和删除操作的时间复杂度是O(1),但是随机访问的时间复杂度是O(n)。这使得LinkedList在需要频繁的插入和删除操作时更加高效。

双链表的结构

双链表是一种链表的扩展,它在每个节点中存储了指向前一个节点和后一个节点的引用。这使得在双链表中,可以通过前一个节点的引用直接访问前一个节点,通过后一个节点的引用直接访问后一个节点。这样,插入和删除操作只需要修改节点的引用,不需要像单链表那样重新连接整个链表。

以下是双链表节点的定义:

class Node<T> {
    T data;
    Node<T> prev;
    Node<T> next;

    Node(T data) {
        this.data = data;
        this.prev = null;
        this.next = null;
    }
}

在LinkedList中,我们使用两个成员变量firstlast来分别表示链表的头节点和尾节点。每个节点都有一个指向前一个节点和后一个节点的引用。当链表为空时,firstlast都指向null。

插入和删除操作

LinkedList提供了一系列用于在链表中插入和删除元素的方法,包括addFirstaddLastaddremoveFirstremoveLastremove等。我们可以通过这些方法在任意位置插入和删除元素。

以下是通过LinkedList进行插入和删除操作的示例代码:

import java.util.LinkedList;

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

        // 在链表末尾插入元素
        linkedList.add("Java");
        linkedList.add("Python");
        linkedList.add("C++");

        // 在链表开头插入元素
        linkedList.addFirst("C");

        // 在链表指定位置插入元素
        linkedList.add(2, "JavaScript");

        // 删除链表开头的元素
        linkedList.removeFirst();

        // 删除链表末尾的元素
        linkedList.removeLast();

        // 删除链表指定位置的元素
        linkedList.remove(1);
    }
}

随机访问的效率

由于LinkedList是一个双链表,它的每个节点只存储了前一个节点和后一个节点的引用,并没有像ArrayList那样使用数组进行存储。因此,LinkedList在进行随机访问时并不高效。假设我们需要访问链表中的第n个元素,我们需要从头节点或尾节点开始,依次遍历到第n个节点。这使得链表在随机访问时的时间复杂度为O(n)。

因此,如果需要频繁进行随机访问操作,建议使用ArrayList。而如果需要频繁进行插入和删除操作,LinkedList是更好的选择。

总结

LinkedList是Java中的一种双链表数据结构,它实现了List接口,并且提供了高效的插入和删除操作。LinkedList通过在每个节点中存储指向前一个节点和后一个节点的引用,使得插入和删除操作的时间复杂度为O(1)。然而,由于没有使用数组进行存储,LinkedList在随机访问时的效率较低,时间复杂度为O(n)。因此,在选择使用LinkedList或ArrayList时,需要根据具体的需求来考虑。

pie
    title LinkedList和ArrayList的使用比例
    "LinkedList" : 45.6
    "ArrayList" : 54.4
erDiagram
    CUSTOMER ||--o{ ORDER : places
    ORDER ||--|{ LINE-ITEM : contains
    CUSTOMER }|..|{ DELIVERY-ADDRESS : uses