Как найти пустую ячейку массива с наименьшим индексом?

Привет. Помогите с задачей.
Исходные данные:
1. Ячейка массива считается пустой, если в ней записано число -1.
2. Ячейка не пустая, если в ней что-то записано, допустим, указатель на объект.
3. Есть массив из 16000 ячеек.
3. Я создаю объекты и последовательно заполняю массив указателями на них, начиная с 0-й ячейки: 0, 1, 2, 3, 4, 5...
Но, в один момент я решаю удалить объект в ячейке с индексом 2. Объект удаляется, а в массив вместо указателя на объект я должен записать -1 (т. е. освобождаю ячейку).
Потом я продолжаю создавать объекты. Но теперь после этого удаления созданный объект должен записаться в ту самую пустую ячейку 2 (т. к. у нее наименьший индекс и она свободна). Когда ячейка 2 снова будет занята, вновь созданные объекты продолжат заполнять массив 6, 7, 8, 9 и т. д.

Естественно, я могу удалять сразу несколько объектов до создания нового объекта.
Допустим, я удалил бы не только объект во 2-й ячейке, но и в 4-й. Тогда новые объекты занимали бы ячейки сначала 2 и 4, а потом как обычно.

Не хочу проходить циклом от начала до конца и проверять, свободна ли ячейка, т. к. у меня будет 16000 объектов минимум (следовательно и массив на 16000 ячеек).

UPD: в распоряжении только обычные массивы и циклы.
  • Вопрос задан
  • 399 просмотров
Решения вопроса 2
wataru
@wataru Куратор тега Алгоритмы
Разработчик на С++, экс-олимпиадник.
Нужно хранить пустые ячейки в списке. У вас будет одна внешняя переменная - указатель на голову этого списка. Можно в качестве указателей в списке использовать сами ячейки.

При добавлении:
Если этот указатель -1 - то надо взять следующий по порядку элемент. Иначе указатель - это пустая ячейка. Ее используйте, но сначала сдвиньте указатель на список пустых элементов вперед по списку.

При удалении просто добавляйте пустую ячейку в начало списка (эта ячейка указывает на текущую голову списка; голова теперь указывает на эту ячейку).

УПД:

Это все выше, если забить на требование заполнения самой левой пустой ячейки. Зато все операции (удаление, поиск пустой ячейки) выполняются за константу и не надо константную дополнительную память.

Если обязательно заполнять самую левую ячейку - то надо писать или приоритетную очередь (через heap) или дерево отрезков (или дерево Фенвика). Тогда операции удаления и поискка будут работать за логарифм и потребуется линейная дополнительная память.
Ответ написан
@Karpion
Ну, я могу предложить то же, что и Wataru : создать очередь со ссылками на пустые элементы массива. Есть даже более красивое решение:
  1. В пустом элементе хранится не "-1", а ссылка на следующий пустой элемент. А начало списка хранится в отдельной переменной.
  2. Соответственно, массив можно инициировать этими ссылками.
Т.е. учёт занятости элементов массива ведётся в этом же массиве, в свободных элементах. Примерно так работает классическая файловая система Unix с дисковым пространством; с той только разницей, что в кластере файловой системы можно хранить много ссылок.

И есть второй вариант:
При каждом удалении элемента производить дефрагментацию свободного места. Сдвигать весь хвост массива слишком сложно, а вот переместить на освободившееся место последний элемент массива = самое то что нужно.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы