Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ГЭ_У_Студентам / ТРПС_2010.doc
Скачиваний:
56
Добавлен:
05.06.2015
Размер:
4 Mб
Скачать

Стеки и очереди в непрерывной памяти

Выберем для линейного списка операции получения доступа, добавления и удаления i-го узла, разрешив их только на концах списка (i=1, i=n) и, в зависимости от допустимого набора операций, определим ряд списковых структур.

ЕСЛИ памяти нет ТО

Переполнение

ИНАЧЕ

Добавить новый узел в вершину стека

Записать Х в вершину стека

ВСЕ ЕСЛИ

procedure PUSH (var S:STACK; NEWOBJ:REAL);

begin

if S.TOP=STACKSIZE then

WRITELN(‘Стек заполнен.')

else

begin

S.TOP:= S.TOP+1;

S.OBJ[S.TOP]:=NEWOBJ

end

end;

  • Удаление объекта из стека

ЕСЛИ стек пуст ТО

Нехватка

ИНАЧЕ

Переписать содержимое из узла вершины в X

Исключить узел из вершины стека

ВСЕ ЕСЛИ

procedure POP (var S:STACK; var OLDOBJ:REAL);

begin

if S.TOP=0 then WRITELN('Стек пуст')

else

begin

OLDOBJ:=S.OBJ[S.TOP];

S.TOP:=S.TOP–1

end

end;

Представление стека в связаннной памяти

  • Стек, как и любой другой линейный список, можно представить в виде односвязного списка следующим образом:

Type

STACK=^Node;

Node=record

Info:Real;

Next:Stack

End;

Var

TOP:Stack

  • TOP - указатель на вершину стека. Если стек пуст, то TOP=nil.

Добавление объекта в стек

Procedure PUSH(var S:Stack;item:integer);

Var NewItem:Stack;

begin

if MaxAvail<=SizeOf(NewItem) then

writeln('НЕ ХВАТАЕТ ПАМЯТИ')

else

begin

New(newitem);

NewItem^.Info:=item;

NewItem^.next:=s;

s:=NewItem;

end;

end;

Удаление объекта из стека

procedure POP (var S:STACK; var OLDOBJ:REAL);

var Old:Stack;

begin

if s=Nil then

WRITELN('CТЕК ПУСТ')

else

begin

OLDOBJ:=S^.info;

Old:=S;

S:=S^.next;

Dispose(old);

End

end;

  • ОЧЕРЕДЬ (Queue, дисциплина обслуживания FIFO, First-In-First-Out, "первым пришел - первым ушел") – линейный список, в котором операция исключения (и обычно всякий доступ) разрешена на одном его конце (в начале), а включения - на другом (в конце).

Представление очереди в непрерывной памяти

  • Представление очереди в непрерывной памяти (в виде массива с максимальным размером QUEUESIZE) можно организовать так:

Const

QUEUESIZE =…

Tyре

Queue=record

OBJ:array[0..QUEUESIZE] of real;

{указатели на первый и последний элементы}

FRONT, REAR: 0..QUEUESIZE;

End;

Var

Q:QUEUE;

В описании типа Queue массив OBJ начинается с 0, т.е. массив значений содержит QUEUESIZE+1 компонент.

[После рис:]

Так как начало и конец очереди непрерывно перемещаются в пределах массива, удобно представить массив в виде кольца. Для обхода «по кольцу» используется операция mod. Если REAR<QUEUESIZE-1, то он увеличивается обычным способом. Если REAR равен QUEUESIZE-1, то он сбрасывается в 0:

REAR+1=(QUEUESIZE-1)+1=QUEUESIZE

QUEUESIZE mod QUEUESIZE=0

Элемент QUEUESIZE не используется для хранения значений.

  • Добавление объекта в очередь

ЕСЛИ Памяти нет ТО

Переполнение

ИНАЧЕ

Добавить узел в конец очереди

Записать Х в последний узел

ВСЕ ЕСЛИ

Procedure ADDQ (var Q:QUEUE; NEWOBJ:REAL);

Begin

With Q do

Begin

REAR:= (REAR+1) mod QUEUESIZE,

if REAR = FRONT then

WRITELN(‘Очередь полна')

Else

OBJ[REAR]:=NEWOBJ

End

end; (* процедуры ADDQ*)

  • Удаление объекта из очереди

ЕСЛИ Очередь пуста ТО

Нехватка

ИНАЧЕ

Переписать содержимое из узла - начала очереди в X

Удалить узел из начала очереди

ВСЕ ЕСЛИ

procedure DELETEQ (var Q : QUEUE; var OLDOBJ:REAL);

begin

with Q do

if REAR=FRONT then

WRITELN(‘Очередь пуста')

Else

Begin

FRONT:=(FRONT + 1) mod QUEUESIZE;

OLDOBJ:=OBJ[FRONT]

End

end; (* процедуры DELETEQ*)

  • Условие REAR=FRONT в ADDQ проверяет, существует ли более 1 свободной позиции между FRONT и REAR (перед проверкой REAR увеличивается на 1). Если существует только одна свободная позиция, очередь - заполнена.