Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Задание к ИДЗ блоковые списки.doc
Скачиваний:
31
Добавлен:
20.06.2014
Размер:
342.53 Кб
Скачать

1.2. Линейные связные индексированные списки

Узловые списки характеризуются высокой производительностью при операциях вставки и удаления – изменения затрагивают всего несколько указателей, обеспечивающих "сцепление" узлов. Если рассматривать вставку/удаление в аспекте модификации структуры в позиции, определяемой итератором, то никакой вид линейных структур не может обеспечить среднюю производительность этих операций выше, чем узловой список. Итератор для двусвязного списка двунаправленный, поэтому есть прямой доступ к "соседям" слева и справа. Итератор для односвязного списка однонаправленный, поэтому доступ к "соседу" слева отсутствует. В этом случае для удаления узла следует устанавливать итератор на элемент, предшествующий удаляемому.

Однако прежде чем осуществлять непосредственно структурные изменения (вставку/удаление), требуется позиционировать итератор на запрошенную позицию. Не возникает проблем с операциями над головным и хвостовым элементами, так как реализация узловых списков обычно предусматривает указатели на головной и хвостовой узлы. Перемещение итератора по цепочке является медленным, из чего следует низкая эффективность доступа к произвольному узлу. В то же время в двусвязном списке доступ к произвольному элементу принято осуществлять перемещением итератора от "головы" к "хвосту", если нужная позицияk < N/2, где N – число элементов в списке, и – от "хвоста" к "голове", если k  N/2. Грубо говоря, движение происходит от ближайшей опорной точки. Если увеличить число опорных точек посредством хранения прямых указателей не только на "голову" и "хвост", но и на некоторые промежуточные позиции, поиск нужной позиции будет ускорен за счет уменьшения длин проходимых цепочек (рис. 6).

Рис. 6. Узловой список с указателями на промежуточные узлы

С каждым прямым указателем ассоциируется номер позиции, и доступ к произвольной позиции осуществляется просмотром получившейся таблицы "указатель-позиция", выбором указателя, который имеет номер позиции, ближайший к нужному, и перемещению по цепочке узлов обычным способом – к "голове" или к "хвосту" (рис. 7).

Адрес

0

100

600

700

1000

Рис. 7. Пример списка с таблицей "указатель-позиция"

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

Техническая реализация индексной таблицы предполагает два варианта: равномерное индексирование (например, когда существует прямой указатель на каждый k-ый элемент, k = 2, 3, ...) и неравномерное индексирование (диапазоны между указателями неодинаковы). Равномерная таблица ускоряет доступ по сравнению с неравномерной, если рассматривается худший случай, однако вопрос о том, какой вариант обеспечивает лучшую эффективность в среднем, требует дополнительного исследования.

Для того чтобы поддерживать индексирование равномерным, при каждой операции вставки/удаления вычисляется новый интервал указателей ' = N'/S, где S – количество ячеек таблицы, отводимых под индексы, N' – новое количество элементов списка. Так как ' – целое, перестройка равномерной таблицы при больших списках требуется не при каждой операции вставки/удаления, например, int(1000/10) = int(1001/10). Если ' =  = N/S, где N – количество элементов до вставки/удаления, изменения указателей не потребуется.

Адрес

0

4

8

12

Адрес

0

5

9

13

Адрес

0

6

10

14

Адрес

0

7

11

15

Рис. 8. Вставка узлов: а – исходный список; б, в, г – вставка в позиции 3, 2, 5

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

В то время как адреса элементов в индексной таблице изменяются далеко не всегда, номера позиций элементов требуют изменения при каждой операции вставки/удаления. Графический пример вставки элементов в индексированный список приведен на рис. 8 (чтобы не загромождать рисунок, показаны только необходимые связи между узлами). Для вставки в позицию 3 (рис. 8, б) необходимо сделать один шаг влево от соответствующего указателя по ссылке previous из узла 4. При этом ссылки не изменяются, изменились пока только номера позиций. Первый интервал стал больше двух остальных. Допустим, вставка осуществляется снова в первый интервал, в позицию 2 (рис. 8, в): ближайшая позиция 0, необходимо сделать два шага вправо от соответствующего указателя по ссылке next из узла 0. Указатели по-прежнему не изменяются. Пусть требуется осуществить еще одну вставку в первый интервал, в позицию 5 (рис. 8, г): ближайшей является ссылка, соответствующая позиции 6, т.е. выполняется один шаг влево от соответствующего указателя по ссылке previous из узла 6. Значение ' изменилось, поэтому необходимо перемещение указателей в таблице для восстановления равномерности. Первый интервал нужно уменьшить на два узла (так как 7-5 = 2), для чего указатель позиции 7 изменяется в два шага по ссылкам previous из соответствующего узла (рис. 8, г). Второй интервал, по аналогии, уменьшается на один узел, для чего указатель позиции 11 изменяется за один шаг по ссылке previous из соответствующего узла. Переиндексированный список, в котором восстановлена равномерная длина интервала, приведен на рис. 9.

Следует отметить, что указатели в связных списках – это не всегда указатели в быстрой оперативной памяти, но часто – на дисковые блоки (или блоки любых блочных устройств). В рассмотренном примере потребовалось три раза осуществлять косвенный доступ по ссылкам из узлов, что является в данном контексте самой медленной операцией, так как все остальные – арифметические операции и операции доступа к ячейкам компактной таблицы – выполняются значительно быстрее.

Адрес

0

5

10

15

Рис. 9. Переиндексированный список

Неравномерное индексирование проще, в нем отсутствует этап передвижения ссылок из таблицы, а только увеличиваются или уменьшаются номера позиций (соответственно, при вставке и удалении), начиная от модифицируемого интервала к концу таблицы. Если позиции модификации равномерно распределены по интервалам, очевидно, равномерность индексации обеспечивается автоматически. Равномерно же индексированный список "скачками" восстанавливает одинаковую ширину интервалов, вне зависимости от распределения позиций модификации.