Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
_Delphi_1курс лекции / Тема Динамические структуры данных.doc
Скачиваний:
68
Добавлен:
23.03.2015
Размер:
330.24 Кб
Скачать

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

После достаточно подробных исследований односвязных списков можно пере­ходить к рассмотрению двухсвязных списков. Как и в случае с односвязными списками, здесь имеется набор связанных между собой узлов, но помимо ссылки на следующий узел существует ссылка и на предыдущий узел:

type

PSimpleNode = ^TSimpleNode;

TSimpleNode = record

Next : PSimpleNode;

Prior : PSimpleNode;

Data : SomeDataType;

end;

Таким образом, двухсвязный список позволяет двигаться по узлам не только вперед, по ссылкам Next, но и назад, по ссылкам Prior. Схематично двухсвязный список показан на рис. 3.4.

Рисунок 3.4. Двухсвязный список

Вставка и удаление элементов в двухсвязном списке

Каким образом вставлять новый узел в двухсвязный список? В односвязном списке для этого нужно было разорвать одну ссылку и вставить две новых, а для двухсвязного списка потребуется разорвать две ссылки и вставить четыре новых. Причем вставку можно выполнять как перед, так и после определенного элемента, поскольку указатель Prior позволяет проходить список в обратном направлении. Фактически операцию "вставить перед" можно запрограммировать как "перейти к предыдущему узлу и вставить после". Поэтому в главе мы рассмотрим только опе­рацию "вставить после".

Ссылка Next нового узла устанавливается на узел, расположенный после за­данного узла, а ссылка Next заданного узла устанавливается на новый узел. Для установки обратных ссылок ссылка Prior нового узла устанавливается на задан­ный узел, а ссылка Prior узла, следующего за новым, устанавливается на новый узел. В коде это выглядит следующим образом:

var

GivenNode, NewNode : PSimpleNode;

begin

• • •

New(NewNode);

.. задать значение поля Data..

NewNode^. Next : = GivenNode^. Next;

GivenNode ^. Next : = NewNode ;

NewNode^.Prior := GivenNode;

NewNode^.Next^.Prior : = NewNode;

В случае с удалением проще всего удалить узел, находящийся после заданного узла. Необходимо установить ссылку Next заданного узла на узел, находящийся после удаляемого, а ссылку Prior узла, находящегося после удаляемого, на за­данный узел.

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

Рисунок 3.5 Вставка нового узла в двухсвязный список

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

var

GivenNode, NodeToGo : PSimpleNode;

begin

• • •

NodeToGo : = GivenNode^. Next ;

GivenNode^.Next : = NodeToGo^.Next;

NodeToGo^.Next^.Prior : = GivenNode;

Dispose(NodeToGo);

Как и для односвязных списков, здесь для обеих операций существуют специ­альные случаи: вставка перед первым элементом списка (т.е. новый элемент ста­новиться первым) и удаление первого элемента списка (т.е. первым становится другой элемент). Поскольку в наших рассуждениях первый элемент считается оп­ределяющим узлом всего списка, код для этих случаев потребуется написать от­дельно

Вставка первого элемента:

var

FirstNode, NewNode : PSimpleNode;

begin

• • •

New(NewNode) ;

.. задать значение поля Data..

NewNode^. Next : = FirstNode;

NewNode^.Prior : = nil ;

FirstNode^.Prior : = NewNode;

FirstNode := NewNode;

Удаление первого элемента:

var

FirstNode, NodeToGo : PSimpleNode;

begin

• • •

NodeToGo:= FirstNode;

FirstNode : = NodeToGo^.Next;

FirstNode^.Prior : = nil;

Dispose(NodeToGo);