Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
TP_теория и практикум.doc
Скачиваний:
11
Добавлен:
20.08.2019
Размер:
861.7 Кб
Скачать

Удаление узла из стека:

Top: = Top^.Link;

Так как Link указывает на следующий узел.

Пример. Модель ожидающей очереди; в каждый момент обслуживают трех первых клиентов.

Program Waiting;

Const NameLenght = 15; {длина имени}

Type NameIndex = 1.. NameLenght;{№ клиента}

NameString = array [NameIndex] of char; {имя клиента}

Natural = 0.. Maxint; {длина очереди}

ClientPointer = ^Client; {указатель на клиента}

C lient = record Name: NameString; {имя клиента}

Nxt: ClientPointer {указатель на следующего} клиент

End; {of record}

Var Head, Tall: ClientPointer; {головной, хвостовой}

Name: array [NameIndex] of char;

Procedure ReadName; { чтение имен}

Var C: NameIndex; {№ символа в имени}

Begin for C: = 1 to NameLenght do

If Eoln then Name [C]: = ‘ ‘

Else begin read (Name [C]); {чтение символа}

Write (Name [C]) {печать символа}

End;

Writln

End; {of ReadName}

Procedure AddClientToList;

Var NewClient: ClientPointer; {указатель на клиента}

Begin New (NewClient); {область памяти для указателя}

If Head = nil then Head: = NewClient

Else Tall^.Nxt: = NewClient;

NewClient^.Name: = Name;

NewClient.Nxt: = nil;

Tall: = NewClient

End; {of AddClientToList}

Procedure ServeClient (HowMany: Natural);

Begin New (ClientToServe);

While (HowMany>0) and (Head<>nil) do

Begin ClientToServe = Head;

Head: = Head^.Nxt;

Writeln (ClientToServe^.Name);

Dispose (ClientToServe);

HowMany: = HowMany – 1

End

End; {of ServeClients}

Begin {of WaitingList}

Head: = nil;

While not eof do

Begin ReadName;

AddClientToList

End;

Writeln;

ServeClients (3)

End. {of WaitingList}

Результат:

Nikita

Balasubramanyam

Nagel

Lecarme

Bello

Pokrovsky

Barron

Yuen

Sale

Price

Nikita

Balasubramanyam

Nagel

Пример. Рассмотрим создание «базы данных», включающей сведения о некоторой группе людей.

Предположим, что каждому человеку соответствует запись:

Type Person = record {перечисление полей}

End; {of record}

Таким образом, мы можем сформировать цепочку или связанный список из таких записей, добавив в них поле типа указатель. Этот список можно использовать для операций поиска и вставки:

Type Link = ^Person;

………………

Person = record

…………

Next: Link;

End; {of record}

Схема связанного списка:

Человек

Человек

Человек

Человек.

Первый

Type Link = ^Person;

……………..

Person = record

…………..

Next: Link;

End; {of record}

Переменная First,относящаяся к типу Link, указывает на первого человека в списке. Поле Next в последней записи в списке имеет значение nil. Например, конструкция First^. Next^. Next указывает на 3 – его человека в списке.

Предположим, что мы можем считывать целочисленные данные, представляющие рост каждого человека в списке. Тогда вышеупомянутая цепочка формируется следующим фрагментом программы:

Var First, P: Link;

H, I: integer;

………….

First: = nil;

For I: = 1 to N do

Begin read (H);

New (P);

P ^. Next: = First;

P . Height: = H;

{какая-то процедура с P}

End;

Список строится в обратном порядке. Для обращения к элементам списка введем новую переменную, скажем Pt, типа Link, которая сможет свободно перемещаться по списку. Чтобы проиллюстрировать процесс поиска, предположим, что нам нужно получить доступ к записи Person с полем Height, имеющим значение 175. Суть поиска состоит в перемещении указателя Pt по списку до тех пор, пока мы не найдем нужную запись.

Pt: = First;

While Pt^.Height<> 175 do Pt: = Pt^.Next;

Словами суть этой конструкции можно выразить так. Пусть Pt указывает на первую запись. До тех пор, пока значение, на которое указывает Pt (поле Height) не равно 175, указателю Pt присваивается значение поля Next текущей записи.

Эта простая процедура поиска работает лишь в случае, когда можно с уверенностью сказать, что в списке есть хотя бы один человек, для которого значение поля Height равно 175. Но разве с такой ситуацией мы сталкиваемся на практике? Если нельзя утверждать, что значение 175 наверняка встретится, необходима проверка на возможность найти его прежде, чем мы дойдем до конца списка. Для начала можно попытаться решить проблему так:

Pt: = First;

While (Pt<>nil) and (Pt^.Height<>175) do

Pt: = Pt^.Next;

Но если Pt = nil, то переменной вообще не существует, и ссылка на нее приводит к ошибке.

Два варианта правильного решения:

  1. Pt: = First;

B: = true;

While (Pt<>nil) and B do

If Pt^.Height = 175 then B: = false

Else Pt: = Pt^.Next

  1. Pt: = First;

While Pt<>nil do

Begin if Pt^.Height = 175

Then goto 13;

Pt: = Pt^.Next

End;

13;

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

New (P) – процедура, создающая новую динамическую переменную Pt^ (ее тип совпадает с тем, на который указывает P) и новое идентифицирующее значение указателя, относящееся к типу P. Это значение тут же присваивается переменной P.

Первым шагом в решении поставленной задачи будет создание новой переменной-указателя. Назовем ее NP. Тогда New (NP) – это создание переменной типа Person.

Следующий шаг: новую переменную, на которую указывает NP, необходимо вставить в список сразу после переменной, на которую указывает Pt.

Связаный список перед вставкой

нового элемента.

Новый

Человек.

Pt NP

Новый элемент вставляется просто путем замены указателей:

NP.F.Next: = Pt^.Next;

Pt^.Next: = NP

Результат этих действий.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]