@Porto_b

Чем плоха вставка в массив в заданную позицию?

Написал для примера программу вставки элемента key в заданную позицию в массиве. Сам код работает, но возник вопрос. Не лучше ли сначала пройтись с конца массива, переставляя элементы, и в конце только a[pos] := key прописать? Просто циклы типа for down to не очень кошерно использовать, мне кажется. Вопрос почти философский, и есть ли алгоритмы лучше чем те, которые я описал?
function  InsertPos(var ar : arInt; key, pos : integer) : boolean;
var count, temp : integer;
begin
...
                count := Length(ar);  
                inc(count);
                 SetLength(ar, count);
...    
                 for j := pos to n-1 do
                                       begin
                                            temp := ar[j];
                                            ar[j] := key;
                                            key := temp;
                                       end;
...
  • Вопрос задан
  • 251 просмотр
Пригласить эксперта
Ответы на вопрос 2
dollar
@dollar
Делай добро и бросай его в воду.
Прелесть массива в том, что он позволяет искать по индексам. И делается это очень быстро, потому что это индексация в самой памяти. То есть вычисляется адрес ячейки памяти с помощью арифметических операций:
БАЗА + [РАЗМЕР ЯЧЕЙКИ] * СМЕЩЕНИЕ
И затем просто происходит обращение на чтение/запись.

Таким образом, чтобы сохранить это свойство массива, необходимо сохранить непрерывную структуру в оперативной памяти. А для этого операция вставки в середину массивы приводит к смещению половины массива на размер одного элемента. То есть это копирование большого куска памяти. Вот это и плохо.

На самом деле, это не плохо и не хорошо. Если это делать редко, а читать данные часто, то это даже отлично. Но если вставка происходит слишком часто, то лучше пересмотреть выбранную архитектуру структуры данных приложения. То есть переписать логику программы так, чтобы не приходилось вставлять в середину массива, обычно это возможно.

А если это не возможно, то может быть, что обращение по индексу не нужно, а только полный перебор (в заданном порядке), тогда можно использовать список, где вставка происходит очень быстро. Ну и так далее, зависит от конкретной задачи. Универсальность и скорость алгоритма, как правило, противоречат друг другу.
Ответ написан
@ddd329
Приветствую!

Если отвечать прямо на поставленный вопрос, то это плохо тем, что в среднем половину элементов придется сдвигать.

Вопрос почти философский, и есть ли алгоритмы более лучше чем которые я описал?

Если вам необходимо поддерживать данный массив в отсортированном виде, то здесь нужен не алгоритм, а другая структура данных - двоичное (бинарное) дерево. Там вам быстрый поиск и вставка обеспечена.

Если вам просто необходимо реализовать такую возможность как вставка в массив, то со сдвигом элементов вправо, вы точно ничего не сделаете, а вот каждый раз увеличивать длину массива это явно плохая идея.

В .Net Framework над массивом реализован абстрактный тип данных (АТД) - список, т.е. List. Так вот там при создании пустого списка, массив имеет длину 4 элемента, если необходимо будет вставить 5-ый элемент, то длина массива просто увеличивается в 2 раза, и станет равна 8-ми. Вставишь 9-ый элемент, то размер увеличиться до 16 и т.д.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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