Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
26
Добавлен:
30.04.2013
Размер:
118.27 Кб
Скачать

12.3. Средства языка паскаль для организации списков

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

  • Структура элемента в Паскале описывается с помощью конструкции типа record.

  • Для связи элементов между собой используется тип «указатель на элемент».

  • В программе для связи со списком должны быть объявлены одна или несколько статических переменных-указателей на элемент списка. Это может быть голова списка (Head), конец списка (Tail) и другие.

В качестве примера приведем объявление типа элемента, информационная компонента которого задается полем Data типа TData.

Type

PItem = ^TItem; {указатель на элемент двухсвязного списка}

TItem = record {описание структуры элемента

двухсвязного списка} Data : TData; {информационное поле элемента}

Prev : PItem; {указатель на предыдущий элемент}

Next : PItem; {указатель на следующий элемент}

end;

{При работе с односвязным списком

указатель на предыдущий элемент не нужен:}

PList = ^TList; {указатель на элемент односвязного списка}

TList = record {описание структуры элемента

односвязного списка} Data : TData; {информационное поле элемента}

Next : PList; {указатель на следующий элемент}

end;

Для создания элемента списка как динамической переменной используют процедуру New:

{Пусть в программе объявлена следующая переменная: }

Var

P : Pitem: {рабочая переменная для временного хранения

указателя на элемент списка}

{Тогда процедура создания динамической переменной для элемента

списка может быть записана следующим образом:}

New(P);

12.4. ТИПОВЫЕ АЛГОРИТМЫ РАБОТЫ СО СПИСКАМИ

При рассмотрении алгоритмов тип информационного поля в них может отличаться. А

var

Head : Pitem; { Указатель на голову списка }

Tail : Pitem; { Указатель на «хвост» списка }

P : Pitem; { Указатель на элемент списка }

переменные, которые будут использованы, считаются объявленными следующим образом:

А

Procedure InitList;

begin

Head := NIL;

Tail := NIL;

end;

1. Инициализация списка.(Создание нового и пустого списка)

А2. Добавить элемент в конец односвязного списка

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

  1. создать элемент, подлежащий добавлению (зарезервировать память)

  2. полям данных присвоить значения входных параметров

  3. Если список не пуст:

  • установить указателю Next последнего элемента ссылку на новый

  • присвоить указателю Next нового элемента NIL

  • передвинуть Tail на новый элемент

  1. Если список пуст

  • установить указатель Head на новый элемент

  • установить указатель Tail на новый элемент

  • присвоить указателю Next нового элемента NIL

Var

pnew :PList; {указатель на новый элемент}

begin

new(pnew);

pnew.data:=indata; {присвоить полю Data значение}

if Head <> nil then {список непустой ?}

Tail^.Next := pnew

else

Head := pnew;

{end if}

pnew.Next:=nil;

Tail := pnew;

end;

А3. Исключить элемент из начала списка (вернув поле данных)

Procedure OutList(var OutDat:TData);

Var

P:Plist;

begin

OutData := Head^.Data;

p:=Head;

Head:=Head^.Next; {присвоить указателю

на голову списка ссылку на новый первый

(бывший второй) элемент}

Dispose(p); {освободить память, занятую элементом}

end;

А4. Удалить элемент из середины списка с освобождением памяти

(для случая односвязного списка):

Р – указатель на удаляемый элемент

Prev - указатель на элемент, стоящий перед удаляемым элементом

Ф

P := Prev^.next;

Prev^.Next := P^.Next;

Dispose(P); {освободить память}

рагмент удаления имеет вид:

А5. Включить элемент (pnew) в середину списка

{Для случая односвязного списка}

pnew^.next:=prev^.next;

prev^.next:=pnew;

А6. Обработать каждый элемент линейного списка

P := Head;

while P <> NIL do begin

Выполнить операцию обработки элемента P^

P := P^.Next; {перейти к следующему элементу}

end;

П

Count := 0;

P := Head;

while P <> NIL do begin

if P^.Data > Value then

Count := Count +1;

{end if}

P := P^.Next;

end;

ример.Пусть информационное поле элемента – целое число. Задача обработки: подсчитать количество элементов, значение информационных полей которых превышает значение Value:

А7. Найти первый элемент, удовлетворяющий некоторому условию

Var

flagFound : boolean;

begin

P := Head;

flagfound := false;

while (P<>NIL) and (not flagfound) do

if (выполнено условие) then

flagfound := true {элемент найден}

else

P := P^.Next;

end;

А8. Уничтожить список с освобождением памяти

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

Это производится следующим образом: Вначале указатель на первый элемент (тот, который записан в указателе на голову списка Head) помещается в рабочую переменную Р. Затем переменнойHeadприсваивается значение указателя на следующий за ним. Это значение в односвязном списке размещается только в поле предыдущего (т.е. удаляемого) элемента. С этого момента бывший первый элемент выведен из списка, и его можно удалить из памяти компьютера, выполнив процедуру Dispose.

P := Head; {Установить указатель на удаляемый элемент}

while P<>NIL do begin

Head := P^.Next; {установить ссылку на следующий}

Dispose(P); {освободить память,

занятую удаляемым элементом}

P := Head; {установить новый удаляемый элемент }

end;

Соседние файлы в папке лекции