Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
САОД Part 1.DOC
Скачиваний:
43
Добавлен:
02.11.2018
Размер:
1.68 Mб
Скачать
    1. Реализация основных операций над односвязным списком

Включение элемента со значением v после элемента с адресом Addr:

Реализация операции приведена ниже. Предполагается, что адрес Addr отличен от nil и элемент с адресом Addr присутствует в списке (эти ситуации должны быть проверены в вызывающей программе). Если список пуст, то новый элемент включается в начало списка.

procedure tList.InsertAfter(Addr: pItem; v: tValue);

var

NewItem: pItem; // вспомогательный указатель на новый элемент

begin

NewItem:= New(pItem); // выделение памяти под новый элемент списка

NewItem^.Value:= v;

if Empty

then begin // если список пуст, включаем в его начало

NewItem^.Next:= nil;

fHead:= NewItem;

end

else begin // список не пуст - включаем после элемента с адресом Addr

NewItem^.Next:= Addr^.Next;

Addr^.Next:= NewItem;

end;

Inc(fSize); // увеличение числа элементов списка на 1

end; // procedure tList.InsertAfter

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

procedure tList.InsertBefore(Addr: pItem; v: tValue);

var

NewItem: pItem; // вспомогательный указатель на новый элемент

begin

NewItem:= New(pItem); // выделение памяти под новый элемент списка

if Empty

then begin // если список пуст, включаем в его начало

NewItem^.Value:= v;

NewItem^.Next:= nil;

fHead:= NewItem;

end

else begin // иначе обмен содержимым элементов NewItem^ и Addr^

NewItem^:= Addr^;

Addr^.Value:= v;

Addr^.Next:= NewItem;

end;

Inc(fSize); // увеличение числа элементов списка на 1

end; // procedure tList.InsertBefore

Исключение элемента, следующего за элементом с адресом Addr:

function tList.DeleteAfter(Addr: pItem): tValue;

var

DisItem: pItem; // вспомогательный указатель на исключаемый элемент

begin

if Addr^.Next=nil

then begin

WriteLn('Исключаемый элемент отсутствует');

Halt;

end

else begin

DisItem:= Addr^.Next;

DeleteAfter:= DisItem^.Value;

Addr^.Next:= DisItem^.Next;

Dispose(DisItem);

end;

Dec(fSize); // уменьшение числа элементов списка на 1

end; // function tList.DeleteAfter

Исключение из списка элемента с указателем Addr. В этом случае необходимо определить адрес элемента, предшествующего исключаемому, что выполняется проходом по списку от его начала с помощью передвигаемого по элементам списка вспомогательного указателя Item типа pItem.

function tList.Delete(Addr:pItem): tValue;

var

Item: pItem; // вспомогательный указатель на элемент списка

begin

if Addr=fHead

then begin // исключается первый элемент

Delete:= Addr^.Value;

fHead:= Addr^.Next;

Dispose(Addr);

end

else begin // поиск элемента, предшествующего исключаемому

Item:= fHead;

while (Item^.Next<>Addr) and (Item<>nil) do Item:= Item^.Next;

if Item=nil

then WriteLn('Исключаемый элемент отсутствует')

else begin

Delete:= Addr^.Value;

Item^.Next:= Addr^.Next;

Dispose(Addr);

end;

end;

Dec(fSize); // уменьшение числа элементов списка на 1

end; // function tList.Delete

Операции tList.DeleteAfter и tList.Delete исключения элементов из списка неприменимы к пустому списку, поэтому перед их выполнением необходимо анализировать значение признака «список пуст». При выполнении этих операций предполагается, что заданный адрес Addr отличен от nil, и элемент с заданным адресом присутствует в списке.

Поиск элемента с заданным значением v в списке:

function tList.Search(v: tValue): pItem;

// Возвращение адреса элемента со значением v

// или nil, если элемент отсутствует

var

Item: pItem;

begin

if Empty

then Search:=nil

else begin

Item:= fHead;

while (Item^.Next<>nil) and (Item^.Value<>v) do Item:= Item^.Next;

if Item^.Value=v then Search:= Item else Search:=nil;

end;

end; // function tList.Search

Включение элемента со значением v в начало списка:

procedure tList.InsertHead(v: tValue);

var

NewItem: pItem; // указатель на новый элемент

begin

NewItem:= New(pItem); // выделение памяти под новый элемент

NewItem^.Value:= v; // запись v в поле значения нового элемента

NewItem^.Next:= fHead; // fHead -> в поле ссылки нового элемента

fHead:= NewItem; // перемещение fHead на новый элемент

Inc(fSize); // увеличение числа элементов списка на 1

end; // procedure tList.InsertHead

Включение элемента со значением v в конец списка:

procedure tList.InsertRear(v: tValue);

var

Item: pItem; // указатель на последний элемент

begin

if Empty

then InsertHead(v) // если список пуст, то включение в начало,

else begin // иначе поиск адреса последнего элемента

Item:= fHead;

while Item^.Next<>nil do Item:= Item^.Next;

InsertAfter(Item, v); // и вставка после последнего элемента

end;

end; // procedure tList.InsertRear

Исключение элемента из начала списка:

function tList.DeleteHead: tValue;

begin

DeleteHead:= Delete(fHead)

end; // function tList.DeleteHead

Исключение элемента из конца списка:

function tList.DeleteRear: tValue;

var

Item:pItem;

begin

Item:= fHead;

while Item^.Next<>nil do Item:= Item^.Next;

DeleteRear:= Delete(Item)

end; // function tList.DeleteRear