Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
osnovy_programmirovanija_v_srede_lazarus.pdf
Скачиваний:
181
Добавлен:
18.03.2015
Размер:
6.53 Mб
Скачать

Глава 4 Типовые алгоритмы обработки информации

____________________________________________________________________

Если в конце списка вместо пустого указателя nil поставить ссылку на начало списка, т.е. на первый элемент списка, то получим так называемый

кольцевой список.

Для всех видов списков можно определить стандартные операции, которые производятся над списками и которые должен уметь реализовывать програм-

мист. К таким операциям относятся добавление нового элемента в список, уда-

ление элемента из списка, поиск нужного элемента в списке. Рассмотрим их.

4.3.5 Стандартные операции с линейными списками

Запишем стандартные операции с линейными списками в виде готовых

процедур и функций.

Процедура добавления (вставки) нового элемента в список:

procedure Insert_MyList(Elem: integer;

var pHead, pCurrent: PMyList);

{pHead - указатель на первый элемент списка ("голову" списка)

pCurrent - указатель на текущий элемент списка}

var

p: PMyList; // рабочий указатель

begin

 

new(p);

// заводим новый элемент

p^.data:=

Elem; // записываем в него данные

{Если список был пустой, то головой списка становится p} if pHead = nil then

begin

p^.next:= nil; pHead:= p;

end

365

4.3 Динамические структуры данных

____________________________________________________________________

else

begin

p^.next:= pCurrent^.next; { в новом элементе делаем ссылку на следующий элемент, который был до вставки} pCurrent^.next:= p; {в текущем элементе делаем

ссылку на новый}

end;

pCurrent:= p; // текущим становится новый элемент

end;

Функция поиска элемента в списке просто проходит все элементы списка по ссылкам от начала до тех пор, пока не будет найден искомый элемент.

function Search_MyList(Elem: integer;

var pHead: PMyList): boolean;

var

p: PMyList; begin

if pHead <> nil then p:= pHead

else begin

writeln(UTF8ToConsole('Список пуст'));

exit;

end;

Search_MyList:= false;

while true do

begin

if p^.data = Elem then

366

Глава 4 Типовые алгоритмы обработки информации

____________________________________________________________________

begin

Search_MyList:= true; break;

end else

if p^.next = nil then break; p:= p^.next;

end;

end;

Функция возвращает true, если требуемый элемент найден.

Процедура удаления элемента из списка:

procedure Delete_MyList(Elem: integer;

var pHead, pCurrent: PMyList);

var

p: PMyList;

pPrev: PMyList; // предыдущий элемент списка find: boolean;

begin

if pHead <> nil then p:= pHead

else begin

writeln(UTF8ToConsole('Список пуст'));

exit;

end;

find:= false;

while true do

begin

367

4.3 Динамические структуры данных

____________________________________________________________________

if p^.data = Elem then

begin

find:= true; break;

end else

if p^.next = nil then break; pPrev:= p;

p:= p^.next; end;

if find then begin

if p = pHead then // если удаляется первый элемент begin

p:= pHead^.next; // запоминаем ссылку на следующий элемент

Dispose(pHead);

// удаляем первый элемент списка

pHead:= p;

// головой списка становится p

end

 

else

 

begin // если удаляется не первый элемент

pPrev^.next:= p^.next; { в предыдущем элементе заменяем ссылку на следующий элемент после удаляемого }

Dispose(p);

pCurrent:= pPrev; // текущим делаем предыдущий элемент

end;

writeln(UTF8ToConsole('Элемент успешно удален'));

end

else writeln(UTF8ToConsole('Элемент не найден'));

end;

368

Глава 4 Типовые алгоритмы обработки информации

____________________________________________________________________

Процедура, прежде чем удалить элемент, должна его найти. Эта часть сов-

падает с функцией поиска. Поскольку код функции поиска небольшой, мы вставили в процедуру непосредственно сам код. В принципе, в процедуре мож-

но вызвать функцию поиска. Для этого необходимо видоизменить функцию та-

ким образом, чтобы она возвращала ссылку на найденный элемент. Если эле-

мента нет, она должна возвращать nil. Предоставляем изменить функцию поис-

ка самому читателю.

Напишем главную программу работы со списком (не забудьте включить в программу процедуры и функции, которые мы только что разобрали):

program operation_list; {$mode objfpc}{$H+} uses

CRT, FileUtil; type

PMyList = ^TMyList; TMyList = record data: integer; next: PMyList; end;

var

pHead, pCurrent: PMyList; Elem, choose: integer;

{Сюда добавьте процедуры и функции, реализующие стандартные операции с линейными списками }

begin

pHead:= nil;

pCurrent:= nil;

repeat

369

4.3 Динамические структуры данных

____________________________________________________________________

writeln(UTF8ToConsole('Выберите нужное действие:')); writeln(UTF8ToConsole('1-ввод элемента списка')); writeln(UTF8ToConsole('2-поиск элемента списка')); writeln(UTF8ToConsole('3-удаление элемента списка')); writeln(UTF8ToConsole('4-просмотр всего списка')); writeln(UTF8ToConsole('5-выход из программы')); readln(choose);

case choose of

1: begin {ввод элемента списка} writeln(UTF8ToConsole('Введите элемент списка')); readln(Elem);

Insert_MyList(Elem, pHead, pCurrent); end;

2: begin {поиск элемента списка}

writeln(UTF8ToConsole('введите искомый элемент'));

readln(Elem);

if Search_MyList(Elem, pHead)then

writeln(UTF8ToConsole('Элемент найден'))

else

writeln(UTF8ToConsole('Элемент не найден')); end;

3: begin {удаление элемента списка} writeln(UTF8ToConsole('введите элемент')); readln(Elem);

Delete_MyList(Elem, pHead, pCurrent); end;

4: begin {Вывод списка на экран}

writeln(UTF8ToConsole('Элементы списка:'));

370

Глава 4 Типовые алгоритмы обработки информации

____________________________________________________________________

writeln;

view_MyList (pHead);

writeln;

end;

end; { end of case }

until choose = 5;

writeln(UTF8ToConsole('Нажмите любую клавишу'));

readkey;

end.

Кроме того, часто встречаются особые списки, где добавление или удале-

ние элементов производится только в начале или в конце списка. Какие это списки:

линейный список, в котором добавление или удаление элементов про-

изводится только в одном конце. Читатель, наверное, уже догадался, что это есть не что иное, как стек!

линейный список, в котором добавление элементов производится на од-

ном конце, а удаление на противоположном конце списка. Если внима-

тельно подумать, то работа такого списка будет напоминать живую оче-

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

Часто очередь называют структурой FIFO (First In - First Out, т.е. "первый пришел, первый ушел").

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

Реализуем рассмотренные динамические структуры с помощью линейных списков.

371

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