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

Узлы связного списка

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

type

SomeDataType=integer;

PSimpleNode = ^TSimpleNode;

TSimpleNode = record

Next : PSimpleNode;

Data : SomeDataType;

end;

Тип PSimpleNode представляет собой указатель на запись TSimpleNode, поле Next которой содержит ссылку на точно такой же узел, а поле Data - сами дан­ные. В приведенном примере тип данных узла задан как SomeDataType. Для пере­хода по ссылке нужно написать примерно следующий код:

var

NextNode, CurrentNode : PSimpleNode;

begin

• • •

NextNode : = CurrentNode^.Next;

Создание односвязного списка

Это тривиальная задача. В самом простом случае первый узел в связном спис­ке описывает весь список. Первый узел иногда называют головой списка.

var

MyLinkedList : PSimpleNode;

Если MyLinkedList содержит nil, списка еще нет. Таким образом, это началь­ное значение связного списка.

{инициализация связного списка}

MyLinkedList :=nil;

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

А каким образом можно вставить новый элемент в связный список? Или уда­лить? Оказывается, что для выполнения этих операций требуется выполнить не­большую работу с указателями.

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

procedure InsertNode(GivenNode: PSimpleNode; D: SomeDataType);

var

NewNode : PSimpleNode;

begin

New(NewNode);

NewNode^.Data:=D; { задать значение поля Data}

NewNode ^. Next : = GivenNode ^. Next ;

GivenNode ^. Next : = NewNode;

end;

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

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

procedure DeleteNode(GivenNode: PSimpleNode);

var

NodeToGo : PSimpleNode;

begin

NodeToGo : = GivenNode^.Next;

GivenNode^.Next : = NodeToGo^.Next;

Dispose(NodeToGo);

end;

Рисунок 3.3. Удаление узла из односвязного списка

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

procedure InsertFirstNode(var MyLinkedList : PSimpleNode; D: SomeDataType);

var

NewNode : PSimpleNode;

begin

New(NewNode);

NewNode^.Data:=D; { задать значение поляData}

NewNode^.Next : = MyLinkedList;

MyLinkedLis t: = NewNode ;

end;

а удаление будет выглядеть так:

procedure DeleteFirstNode(var MyLinkedList : PSimpleNode);

var

NodeToGo : PSimpleNode;

begin

NodeToGo : = MyLinkedList; {GivenNode^.Next;}

MyLinkedList: = NodeToGo^. Next;

Dispose(NodeToGo);

end;

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