← Назад к вопросам

Какая временная сложность операции доступа по индексу в LinkedList?

1.2 Junior🔥 61 комментариев
#Коллекции

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Временная сложность доступа по индексу в LinkedList

Временная сложность операции доступа по индексу в LinkedList составляет O(n), где n — размер списка. Это одна из основных причин, почему ArrayList предпочтителен для операций случайного доступа.

Почему O(n)?

LinkedList хранит элементы в виде цепочки связанных узлов. Для доступа к элементу по индексу нужно пройти от начала (или конца) списка, переходя от одного узла к другому через ссылки.

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

Node<E> node(int index) {
    // Если индекс ближе к началу, начинаем с head
    if (index < (size >> 1)) {
        Node<E> x = first;
        for (int i = 0; i < index; i++)
            x = x.next;  // Переходим к следующему узлу
        return x;
    } else {
        // Если индекс ближе к концу, начинаем с tail
        Node<E> x = last;
        for (int i = size - 1; i > index; i--)
            x = x.prev;  // Переходим к предыдущему узлу
        return x;
    }
}

Практический пример

LinkedList<Integer> list = new LinkedList<>();
for (int i = 0; i < 1000; i++) {
    list.add(i);
}

// Доступ к элементу с индексом 0: O(1) — это first
int first = list.get(0);  // Находится сразу

// Доступ к элементу с индексом 500: O(500)
int middle = list.get(500);  // Нужно пройти через 500 узлов

// Доступ к элементу с индексом 999: O(1) — это last
int last = list.get(999);  // LinkedList оптимизирует, начиная с конца

Сравнение с ArrayList

ArrayList<Integer> arrayList = new ArrayList<>();
LinkedList<Integer> linkedList = new LinkedList<>();

for (int i = 0; i < 1000; i++) {
    arrayList.add(i);
    linkedList.add(i);
}

// ArrayList: get() это O(1) — прямой доступ к массиву
int val = arrayList.get(500);  // Мгновенно

// LinkedList: get() это O(n) — нужно обойти узлы
int val = linkedList.get(500);  // Проходит через 500 узлов

Оптимизация в LinkedList

Java реализует небольшую оптимизацию: если индекс ближе к концу списка, начинает с конца:

LinkedList<String> list = new LinkedList<>();
for (int i = 0; i < 100; i++) {
    list.add("item " + i);
}

// Начинает с head (индекс < 50)
list.get(10);   // O(10) операций

// Начинает с tail (индекс >= 50)
list.get(99);   // O(1) операция (это last)
list.get(98);   // O(2) операции
list.get(90);   // O(10) операций

Временная сложность других операций LinkedList

LinkedList<E> list = new LinkedList<>();

list.add(element);              // O(1) — добавление в конец
list.addFirst(element);         // O(1) — добавление в начало
list.addLast(element);          // O(1) — добавление в конец
list.add(index, element);       // O(n) — вставка в произвольное место
list.get(index);                // O(n) — доступ по индексу
list.set(index, element);       // O(n) — замена по индексу
list.remove(index);             // O(n) — удаление по индексу
list.removeFirst();             // O(1) — удаление с начала
list.removeLast();              // O(1) — удаление с конца
list.contains(element);         // O(n) — поиск элемента

Когда использовать LinkedList?

// Хорошо для LinkedList:
LinkedList<Task> queue = new LinkedList<>();
queue.addFirst(task);       // O(1)
Task first = queue.removeFirst();  // O(1)

// Плохо для LinkedList:
for (int i = 0; i < list.size(); i++) {
    list.get(i);            // O(n²) общая сложность!
}

// Хорошо для LinkedList (итерация):
for (Integer num : list) {  // O(n)
    System.out.println(num);
}

Почему ArrayList лучше для доступа по индексу

public E get(int index) {
    // ArrayList: прямой доступ к элементу массива за O(1)
    return elementData[index];  // Математический расчёт адреса памяти
}

Вывод

  • LinkedList.get(index)O(n) в худшем случае
  • ArrayList.get(index)O(1) всегда
  • Если часто нужен доступ по индексу — используй ArrayList
  • Если часто добавляют/удаляют в начало/конец — используй LinkedList
  • Для итерации оба работают одинаково хорошо через foreach
Какая временная сложность операции доступа по индексу в LinkedList? | PrepBro