Назад к вопросам
Middle
67
questionbank
Как работает динамический массив?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
В Python динамический массив (список, list) реализован как массив указателей на объекты.
Когда список создается или увеличивается:
- Выделяется блок памяти для хранения указателей. Размер этого блока больше текущего количества элементов.
- Существующие указатели копируются в новый блок.
- В случае добавления элемента, указатель на него помещается в следующий свободный слот.
Особенности:
- Выделение памяти: Python не выделяет память сразу для всех объектов, а только для указателей на них. Сами объекты хранятся в другом месте памяти.
- Перевыделение памяти: При добавлении элементов, если текущий блок памяти заполнен, Python выделяет новый, больший по размеру блок и копирует в него старые указатели. Эта операция называется амортизированное O(н), поскольку большинство вставок занимают O(1), а редкие перевыделения делают среднее время линейным относительно размера массива.
- Удаление: При удалении элемента из середины массива, элементы справа сдвигаются влево, чтобы заполнить образовавшийся пробел. Это операция O(н). Удаление с конца занимает O(1).
- Доступ по индексу: Доступ к элементу по индексу занимает O(1), так как адрес указателя вычисляется простым смещением.
Таблица операций и их сложности:
| Операция | Средняя сложность | Худшая сложность (из-за перевыделения) |
|---|---|---|
| Доступ по индексу | O(1) | O(1) |
| Вставка в конец | O(1) | O(н) |
| Вставка в начало | O(н) | O(н) |
| Вставка в середину | O(н) | O(н) |
| Удаление с конца | O(1) | O(1) |
| Удаление с начала | O(н) | O(н) |
| Удаление в середину | O(н) | O(н) |
# Пример работы динамического массива (списка) в Python
my_list = [] # Создание пустого списка (динамического массива)
# Добавление элементов в конец - чаще всего O(1)
my_list.append(1)
my_list.append(2)
my_list.append(3)
# my_list сейчас [1, 2, 3]. Если нужно перевыделить память, это O(н).
# Вставка в начало - O(н)
my_list.insert(0, 0) # [0, 1, 2, 3]
# Доступ по индексу - O(1)
print(my_list[2]) # Выведет 2
# Удаление с конца - O(1)
my_list.pop() # Удаляет 3. my_list сейчас [0, 1, 2]
# Удаление из середины - O(н)
del my_list[1] # Удаляет 1. my_list сейчас [0, 2]