Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка DELPHI.DOC
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.73 Mб
Скачать

Двунаправленные списки

Структура двунаправленного связанного списка приводится на рис. 42. Данная структура соответствует следующему объявлению: Type PStroka = ^Stroka;

Stroka = record

Info:string;

Pred,Sled: PStroka;

End;

Рис. 42 Структура двунаправленного списка.

Для построения связей между отдельными элементами списка используются два указателя: Pred – связь с предыдущим элементом и Sled – связь с последующим элементом. Соответственно имеет место ограничение связей элементов списка и слева и справа с помощью пустого указателя nil. Построим список из трёх элементов, как в предыдущем случае и при условиях предыдущей задачи.

New(Spisok); {Начало списка}

Spisok^.Info:=S1; {Запись строки S1 в список}

Spisok^.Pred:=nil; {Ограничение связей списка слева}

New(P); {Новый элемент списка}

P^.Info:=S2; {Запись строки S2 в элемент P}

P^.Pred:=Spisok; {Связь с предыдущим элементом}

Spisok^.Sled:=P;{Подключение элемента два в список}

New(P); {Третий элемент списка}

P^.Info:=S3; Запись строки S3 в элемент P}

P^.Pred:=Spisok^.Sled; {Связь с предыдущим элементом}

Spisok^.Sled^.Sled:=P; {Подключение элемента 3 в список}

P^.sled:=nil; {Конец списка}

P:=nil;

На основе двунаправленного списка возможно формирование кольцевых связанных списков, когда самый первый элемент списка ссылается на последний элемент, а последний – на первый элемент.

Стеки, очереди

Предполагается, что элементы в списках могут добавляться и извлекаться в произвольном порядке. Существуют списки с заранее заданными процедурами добавления и извлечения элементов. Это стеки и очереди. Очередью называется однонаправленный или двунаправленный связанный список с процедурой работы FIFO – First In, First Out (первым пришёл, первым ушёл). В списках типа очередь элемент добавляется в конец списка, а извлекается из начала списка. Стек – связанный список с процедурой работы LIFO – Last In, First Out (последним пришёл, первым ушёл). Элементы стека добавляются в конец списка и извлекаются из конца списка.

Идентифицируется очередь с помощью двух указателей: запоминается начало очереди и конец списка. Стек можно идентифицировать одним указателем, помечая дно стека с помощью nil.

Бинарные деревья

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

Бинарное дерево, по определению, - это иерархическая структура, схематично представляемая, например так, как на рис. 43.

Рис. 39. Структура бинарного дерева.

Бинарное дерево имеет узлы, в которые может входить одна ветвь, а выходить не более двух (бинарное). Верхняя вершина не имеет входа и называется корнем. Построить бинарное дерево можно следующим образом. Пусть имеется набор числовых оценок для некоторого ключа, например, такой: 35, 86, 49, 27, 31, 56, 62, 44, 29, 26, 33, 88. Примем, что вправо по ходу дерева, начиная от корня, значение ключа увеличивается, а влево – уменьшается. Тогда получим структуру дерева, представленную на рис. 43. Структуру бинарного дерева синтаксически можно объявить следующим образом:

Type

PDerevo=^Derevo;

Derevo=record

Key:word;

Info: string;

Left,Right: Pderevo;

End;

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

Program Prim;

Type PStroka = ^Stroka;

Stroka = record

Info:string;

Sled: PStroka;

End;

Var T:TextFile;

P,Pbegin,Pend:PStroka;

S:string;

Begin

New(Pbegin);

Pend:=Pbegin;

P:=Pbegin;

AssignFile(T,’A.txt’);

Reset(T);

While not eof(T) do begin

Readln(T,S);

P^.Info:=S;

Pend^.Sled:=P;

Pend:=P;

New(P);

End;

Pend^.sled:=nil;

Dispose(P);

CloseFile(T);

End.

Здесь указаталь Pbegin является идентификатором начала очереди, поэтому ему ещё до начала цикла выделяется память. Указатель Pend необходим для запоминания последнего элемента очереди. Вспомогательный указатель P позволяет обеспечить циклические вычисления. Цикл построен так, что указатель Pend постоянно продвигается по списку, обеспечивая добавление очередного элемента в конец очереди.