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

2. Создание первого элемента списка и заполнение полей:

new(current);

current^.data:= ’данные в первом элементе списка ’;

current^.next:=nil;

Поле current^.next является указателем, доступ к его содержимому осуществляется через указатель current.

3. Создание следующего элемента и связывание его с первым элементом:

head:=current;

new(last);

last^.data:= ’данные во втором элементе списка ’;

last^.next:=nil;

current^.next:=last;

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

4. Создание списка из n элементов:

head:= nil;

for i:=1 to n do

begin

new(current);

readln(current^.data);

current^.next:=nil;

if head=nil then

head:=current

else

last^.next:= current;

last:= current;

end;

5. Удаление элемента списка:

Удаление элемента из списка заключается, в первую очередь, в переопределении указателей, связанных с данным элементом (указывающих на него), но удаленный элемент данных при этом продолжает занимать память, хотя доступ к нему будет потерян. Для корректной работы с динамическими структурами следует освобождать память при удалении элемента структуры:

dispose(current);

Линейный двусвязный (двунаправленный) список

Односвязный список неудобен тем, что при попытке вставить некоторый элемент перед текущим элементом требуется обойти список, начиная с заголовка, чтобы изменить значение указателя в предыдущем элементе списка. Чтобы устранить данный недостаток, вводится второй указатель в каждом элементе списка: первый указатель связывает данный элемент со следующим элементом, а второй – с предыдущим. Такая динамическая структура данных называется линейным двусвязным (двунаправленным) списком.

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

1. Объявление данных двусвязного списка:

type

listPtr = ^list;

list = record

number, data: integer;

next, prev: listPtr;

end;

В данном случае number поле для хранения порядкового номера элемента, data – поле для хранения данных элемента, prev и next – указатели на предыдущий и последующий элемент соответственно.

2. Пример программы работы с двусвязным списком.

Программа выполняет следующие операции с элементами списка:

  • добавление элемента в начало списка и вставка элемента после текущего;

  • удаление текущего элемента;

  • вывод списка.

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

Одна из возможных реализаций программы с использованием модульного программирования

Program mod_list; { основная программа }

uses menu_proc;

begin

menu_work;

end.

Unit types; { модуль описания типов }

Interface { интерфейсная часть }

type

point=^element;

element=record

data:string[10];

last, next:point;

end;

Implementation { часть реализации в данном модуле пустая }

{ часть инициализации в данном модуле отсутствуют }

end.

Unit work_proc; { модуль процедур обработки линейного двусвязного списка }

Interface { интерфейсная часть }

uses types;

var

head: point;

pnt, pcur, p: point;

procedure current_elem(head: point, var pcur:point); { назначение элемента текущим }

procedure output_list(head:point); { вывод списка элементов }

procedure add_ins(var pcur:point); { добавление или вставка элемента после текущего }

procedure del_elem(head,pcur:point); { удаление текущего элемента }

procedure del_list(var head:point); { удаление списка }

Implementation { часть реализации }

procedure current_elem; { назначение текущего элемента }

var

s: string[10];

pr: boolean;

begin

readln(s);

p:=head;

pr:=false;

repeat

if p^.data=s then

begin

pcur:=p;

pr:=true;

end

else

p:=p^.next;

until (pr) or (p=nil);

end;

procedure output_list; { вывод списка элементов }

var

i: integer;

begin

p:=head;

i:=0;

repeat

if i=0 then

writeln('head')

else

writeln('(',i,') ',p^.data);

p:=p^.next;

i:=i+1;

until p=nil;

end;

procedure add_ins; { добавление или вставка элемента в список после назначенного текущего элемента }

begin

new(p);

readln(p^.data);

p^.last:=pcur;

p^.next:=pcur^.next;

pcur^.next:=p;

pnt:=p^.next;

if pnt<>nil then

pnt^.last:=p;

end;

procedure del_elem1(head:point, var pcur:point, var ppr: boolean); { вложенная процедура процедуры del_elem удаления текущего элемента }

begin

p:=head;

while (p^.next<>pcur) and (p^.next<>nil) do

p:=p^.next;

if p^.next=nil then

begin

pcur:=head;

ppr:=true;

end

else

begin

p^.next:=pcur^.next;

dispose(pcur);

if p^.next<>nil then

p^.next^.last:=p;

end;

end;

procedure del_elem; { удаление текущего элемента }

var

pr: boolean;

begin

if (pcur=head) and (head^.next=nil) then

begin

writeln('List is empty');

readln;

end

else

begin

pr:=false;

del_elem1(head,pcur,pr);

if pr then

begin

writeln('There is no such element of the list');

readln;

end;

end;

end;

procedure del_list; { удаление списка }

begin

repeat

p:=head;

head:=head^.next;

dispose(p);

until head=nil;

end;

{ часть инициализации в данном модуле отсутствует }

end.

Unit menu_proc; { модуль формирования меню }

Interface

uses crt, types, work_proc;

var

n: byte;

procedure menu_work;

Implementation

procedure menu_work;

begin

new(pcur);

head:=pcur;

pcur^.next:=nil;

pcur^.last:=nil;

repeat

clrscr;

writeln('1 - set current element');

writeln('2 - output list');

writeln('3 - add or insert element after current one');

writeln('4 - delete current element');

writeln('0 - exit');

readln(n);

clrscr;

case n of

1: begin

writeln('set current element: ');

current_elem(head,pcur);

end;

2: begin

output_list(head);

readln;

end;

3: begin

writeln('input element:');

add_ins(pcur);

end;

4: del_elem(head,pcur);

end;

until n=0;

del_list(head);

end;

end.

Соседние файлы в предмете Программирование на Pascal