Inherited create;

sp1:=nil; spk:=nil;

end;

. . . . . . . . . . . . .

Var stec,st1,turn,tr1:Tlist; inf:Tinf;

Begin

stec:=Tlist.create;

stec.Add1(inf);

stec.print;

. . . . . . .

stec.free;

Ниже приведены наиболее часто используемые методы данного класса для работы со списком.

4.4. Начальное формирование, добавление и удаление элементов однонаправленного списка

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

Добавление новой записи в конец списка с двумя точками доступа sp1, spk осуществляется следующей процедурой:

Листинг 4.5

Procedure Tlist.Addk(Inf:TInf);

begin

if spk=Nil then begin // если список пуст

New(spk);

spk^.A:=Nil;

spk^.Inf:=inf;

sp1:=spk;//если очередь

end;

else begin

New(spk^.A);//вместо Nil в адресную часть последней записи //помещается выделенный новый адрес

spk:=spk^.A;//этот адрес запоминается также в spk

spk^.Inf:=Inf;

spk^.A:=Nil;end;

end;

В результате первого обращения к этой подпрограмме (если sp1=spk=Nil) в списке размещается одна заявка. При этом инициируются и в дальнейшем поддерживаются два указателя sp1 - адрес 1-й записи, spk - адрес последнeй.

Добавление новой записи в начало списка:

Листинг 4.6

Procedure Tlist.Add1(Inf:TInf);

begin

if sp1=Nil then begin // если список пуст

New(sp1);

sp1^A:=Nil;

sp1^.Inf:=Inf;

spk:=sp1;//если очередь

end;

else

begin

New(sp);

sp^.Inf:=Inf;

sp^.A:=sp1;

sp1:=sp;

end;

end;

Заметим, что оператор if в этой процедуре используется только для поддержания работы списка с двумя точками входа. Поэтому при работе со стеком, имеющим только одну точку входа sp1 переменную spk и оператор if в этой процедуре можо убрать и назвать метод, например Addst.

Прочесть и стереть информацию из начальной записи списка можно с помощью следующей процедуры:

Листинг 4.7

Procedure Tlist.Reаd1(var Inf:Tinf);

begin if sp1<>Nil then begin

Inf:=sp1^.Inf;

sp:=sp1;

sp1:=sp1^.A;

if sp1=Nil then spk:=Nil;

Dispose(sp);

end end;

здесь второй оператор if необходим для поддержания очереди, поэтому при работе со стеком этот оператор if можно убрать и назвать метод Readst.

Чтение и стирание последней записи из списка:

Листинг 4.8

Procedure Tlist.Reаdk(var Inf:Tinf);

Begin

If spk<>Nil then begin

Inf:=spk.Inf;

if sp1=spk then //если запись только одна

begin Dispose(spk); sp1:=Nil; spk:=Nil end

else begin

sp:=sp1;//поиск предпоследней записи:

while sp^.A<>Spk do sp:=sp^.A;

Dispose(spk);//освобождение памяти

spk:=sp;//запись адреса предпоследней записи

spk^.A:=Nil;

end end;

end;

Как видим, удаление последней записи в рассматриваемом однонаправленном списке значительно сложнее, чем первой. Поэтому при работе с очередью добавление новой записи производится в конец списка (Addk) а удаление из начала (Read1). При работе со стеком добавление и чтение записей производят через начальный адрес sp1.

Распечатать текущий список можно, используя следующую процедуру:

Листинг 4.8

Procedure Tlist.Print;

begin

sp:=sp1;

While sp <> Nil do

begin

Writeln(sp^.Inf);

sp:=sp^.A;

end;

end;

Эту процедуру легко модифицировать для поиска нужного элемента, подсчета количества элементов.

Чтение и удаление элемента из середины однонаправленного списка сделать просто, если известен адрес ячейки spi находящейся перед удаляемой:

Листинг 4.9

Procedure Tlist.ReadAfter(spi:Psel;var Inf:TInf);

begin

sp:=spi^.A;//в sp адрес следующей за spi

Inf:=sp^.Inf;

spi^.A:=sp^.A;

Dispose(sp);

end;

Добавление элемента в середину однонаправленного списка послеэмента с адресом spi:

Листинг 4.10

Procedure Tlist.AddAfter(spi:Psel,Inf:TInf);

begin

New(sp);

sp^.Inf:=Inf;

sp^.A:=spi^.A;

spi^.A:=sp;

end;

Чтение и удаление ячейки с адресом spi из списка, и добавление в список ячейки перед spi осуществляется более сложно, с использованием ReadAfter; АddAfter и дополнительного копирования информационной ячейки:

Листинг 4.11

Procedure Tlist.Readspi(spi:Psel;var Inf:TInf);

begin

Inf:=spi^.Inf;

RedAfter(spi,spi^.Inf);//читаем и удаляем след. за spi

end;

Procedure Tlist.AddBefore(spi:Psel;Inf:Tinf);

begin

AddAfter(spi,spi^.Inf);//вставляем spi после spi

spi^.Inf:=Inf;

end;

Используя приведенные выше процедуры, нетрудно составить программы по формированию и обслуживанию всевозможных однонаправленных списков.