Какая разница в производительности при добавлении элемента в начало и в конец буфера?

«Какая разница в производительности при добавлении элемента в начало и в конец буфера?» — вопрос из категории Алгоритмы и структуры данных, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Добавление в конец (append) обычно имеет сложность O(1), если в буфере есть свободная емкость. Это происходит потому, что элемент просто помещается в следующую доступную позицию.

Добавление в начало (insert) имеет сложность O(n), так как требует сдвига всех существующих элементов на одну позицию для освобождения места.

Пример на Swift (Data):

var buffer = Data([1, 2, 3])
// Медленно: O(n)
buffer.insert(0, at: 0) // Теперь [0, 1, 2, 3]
// Быстро: O(1) (амортизированно)
buffer.append(4)        // Теперь [0, 1, 2, 3, 4]

Практическое следствие: Для частых операций вставки в начало следует рассмотреть другие структуры данных, такие как:

  • Двусвязный список (LinkedList) – вставка в начало O(1).
  • Дек (Deque) – эффективные операции с обоих концов.
  • Использование reversed() – хранение данных в обратном порядке для превращения добавления в конец во вставку в начало.