Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
структуры и алгоритмы / Лекции_лабор_структ.doc
Скачиваний:
56
Добавлен:
04.06.2015
Размер:
2.98 Mб
Скачать

4.3 Двусвязные списки

Нередко при просмотре линейного списка возникает необходимость продвижения в любом из двух направлений по цепочке элементов. Такую возможность обеспечивает двусвязный список. Линейный двусвязный список отличается от односвязного списка тем, что каждый его элемент содержит два указателя, один из которых (прямой указатель) адресует, как и в односвязном списке, следующий указатель, а другой указатель (обратный) адресует предыдущий элемент списка. Позднее мы познакомимся с более общим видом двусвязного списка. Логическая структура линейного двусвязного списка приведена на рис.4.3. В структуру двусвязного списка добавлен указатель конца списка. Линейность его вытекает из того, что каждый из двух указателей в любом элементе списка (кроме крайних элементов, в которых один из указателей пуст) задает линейный порядок элементов, обратный по отношению к порядку, устанавливаемому другим указателем. Следует отметить, что начало и конец двусвязного списка логически эквивалентны, поскольку доступ к тому или иному элементу может быть осуществлен с любого конца списка. Так как в двусвязном списке можно продвигаться от элемента к элементу двумя противоположными путями, то в конце каждого из них в поле соответствующего указателя находится признак пустого указателя Æ.

Наличие двух указателей в каждом элементе заметно усложняет список и приводит к дополнительным затратам памяти, но в то же время обеспечивает более эффективное выполнение операций над списком. Очевидно, что из описанного двусвязного списка нетрудно получить кольцевой двусвязный список. Для этой цели следует два пустых указателя заменить указателями противоположных концов списка, как это показано на рис. 4.4. Из-за кольцевого характера этой разновидности двусвязного списка в его структуру не нужно включать указатель конца списка.

Прежде чем рассматривать операции над связными списками, введем обозначения переменных, которые потребуются при описании соответствующих операций. Данные, хранящиеся в содержательном поле элемента списка, обозначим DATA. В соответствии с определением связного списка DATA пред-

ставляет собой в общем случае запись, причем структура этой записи одинакова для каждого элемента списка. В элементе односвязного списка единственный указатель следующего элемента будем обозначать LINK, а в элементе двусвязного списка указатели следующего и предыдущего элементов - соответственно SLINK и PLINK. Указателю начала списка, применительно к которому будет исследоваться та или иная операция, назначим имя START. Отметим, что указатель START хранится в дескрипторе списка. Кроме указателя START в процессе обработки списка может потребоваться рабочий указатель, который принимает значение адреса того или иного элемента списка. Дадим рабочему указателю имя PNTER.

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

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

Обозначим указатель начала свободного списка идентификатором FREE. Условимся также считать, что выражение DATA (PNTER) представляет данные того элемента списка, который адресуется указателем PNTER. Соответственно выражение LINK (PNTER) имеет значение адреса, или связки, элемента, адресуемого указателем PNTER. И, наконец, запись PNTER ¬ LINK (PNTER) выражает присваивание указателю PNTER значение связки LINK того элемента, который в данный момент адресуется указателем PNTER (это соответствует перемещению указателя на следующий элемент списка).

Обратимся теперь к первой из двух основных операций над списком - операции включения элемента в список - и проиллюстрируем ее для случая односвязного списка. Список, в который надлежит включить новый элемент, может быть пуст или содержать один, два элемента и более. Новый элемент может включаться в начало списка, в конец или куда-нибудь внутрь списка. В зависимости от этого операция включения имеет свои особенности выполнения. Предположим, что обрабатываемый функциональный список может содержать произвольное конечное число элементов и требуется включить в него новый элемент вслед за элементом того же списка, адресуемым рабочим указателем PNTER. Допустим, что новый элемент уже взят из свободного списка и его данные DATA сформированы должным образом. Указатель NEW адресует этот элемент. Исходная ситуация показана на рис.4.5, на которой пунктирная стрелка указывает связку, подлежащую разрыву.

Операция включения нового элемента в список выполняется следующим образом. В поле связки включаемого элемента заносится содержимое поля связки того элемента, вслед за которым в списке должен быть включен новый элемент. Тем самым устанавливается связь включаемого элемента со следующим за ним элементом списка. Затем в поле связки элемента, вслед за которым включается новый элемент, заносится значение указателя NEW, в результате чего устанавливается связь нового элемента с предыдущим в списке элементом. Эти действия применительно к односвязному списку иллюстрируются на рис.4.6, на котором подчеркнуты связки, модифицированные в результате операции.

Подробно алгоритмы включения нового элемента в односвязный список и исключения элемента из односвязного списка изложены в [5]. В двусвязных списках обе операции усложняются вследствие необходимости модифицировать не один, а два указателя в соответствующих элементах. Разработку алгоритмов включения и исключения для двусвязных списков, а также для кольцевых односвязного и двусвязного списков оставляем студентам в качестве упражнений.

Соседние файлы в папке структуры и алгоритмы