3.5 Выбор элемента из очереди

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

procedure SelectFromQueue( var FirstElem, LastElem: Queue; var Result: TypeOfElem);

var

ServiceVar: Queue;

begin

if not ( ( FirstElem= nil ) and ( LastElem= nil ) ) then begin

Result:= FirstElem^.Elem;

ServiceVar:= FirstElem;

{убираем 1-ый элемент из очереди}

FirstElem:= FirstElem^.NextElem;

{был ли это последний элемент}

if FirstElem= nil then

LastElem:= nil;

dispose( ServiceVar )

end

end;

3.6 Стек на базе списка

Из механизма LIFO следует, что в стеке доступен только последний занесенный его элемент √ так называемая вершина стека. Главный элемент, представляющий весь список как единый объект, в случае стека оказывается лишним, его роль выполняет вершина стека. Элемент, занесенный в стек раньше других имеет ссылку nil (см. рис. 6).

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

type

TypeOfElem= {};

Assoc= ^ElementOfStack;

ElementOfStack= record

Elem: TypeOfElem;

NextElem: Pointer

end;

Stack= Assoc;

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

3.7 Создание (очистка) стека

Для создания нового пустого или очистки существующего стека достаточно присвоить указателю на первый его элемент (вершину) значение nil.

procedure CreateStack ( var StackHead: Stack);

begin

StackHead:= nil

end;

3.8 Проверка стека на пустоту

Условием пустоты стека является значение его вершины, равное nil.

function StackIsClear( var StackHead: Stack ): Boolean;

begin

StackIsClear:= ( StackHead= nil )

end;

3.9 Занесение элемента в стек

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

procedure IncludeInStack( var StackHead: Stack; NewElem: TypeOfElem );

var

ServiceVar: Stack;

begin

{создание нового элемента}

&nbspnew( ServiceVar );

ServiceVar^.Elem:= NewElem;

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

ServiceVar^.NextElem:= StackHead;

StackHead:= ServiceVar

end;

3.10 Выбор элемента из стека

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

procedure SelectFromStack( var StackHead: Stack; var Result: TypeOfElem);

var

ServiceVar: Assoc;

begin

if StackHead <> nil then begin

{выбор элемента из вершины}

Result:= StackHead^.Elem;

{запоминание ссылки на старую вершину}

ServiceVar:= StackHead;

{исключение из стека и уничтожение элемента}

StackHead:= StackHead^.NextElem;

dispose( ServiceVar )

end

end;

Необходимо обратить внимание на введение вспомогательной переменной ссылочного типа ServiceVar для осуществления удаления элемента. Типична ошибка, связанная с попыткой решить эту задачу через dispose( StackHead ).

Разберем решение типичной задачи, связанной с обработкой стека.

Текст задания

Используя стек (считать уже описанными тип Stack с информационным элементом типа Char, функцию StackIsClear (проверка пустоты стека) и процедуры CreateStack (очистка стека), IncludeInStack (вставка элемента в стек), SelectFromStack (выборка элемента из стека)) решить следующую задачу: в текстовом файле f записана без ошибок формула следующего вида:

<формула>::= <цифра>|M(<формула>,<формула>)|m(<формула>,<формула>)

цифра::= 0|1|2|3|4|5|6|7|8|9

где M обозначает функцию max, а m √ min. Вычислить (как целое число) значение данной формулы (например, M( 5, m( 6, 8)): 6).

Решение

program StackSample;

type

FileType= File of Char;

var

Source: FileType;

function formula( var t: FileType ): integer;

type

TypeOfElem= Char;

Assoc= ^ElementOfStack;

ElementOfStack= record

Elem: TypeOfElem;

NextElem: Pointer

end;

Stack= Assoc;

var

S: Stack;

c, op, x, y: char;

procedure CreateStack ( var StackHead: Stack);

begin

StackHead:= nil

end;

function StackIsClear( var StackHead: Stack ): Boolean;

begin

StackIsClear:= ( StackHead= nil )

end;

procedure IncludeInStack( var StackHead: Stack; NewElem: TypeOfElem );

var

ServiceVar: Stack;

begin

{создание нового элемента}

new( ServiceVar );

ServiceVar^.Elem:= NewElem;

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

ServiceVar^.NextElem:= StackHead;

StackHead:= ServiceVar

end;

procedure SelectFromStack( var StackHead: Stack; var Result: TypeOfElem );

var

ServiceVar: Assoc;

begin

if StackHead <> nil then begin

{выбор элемента из вершины}

Result:= StackHead^.Elem;

{запоминание ссылки на старую вершину}

ServiceVar:= StackHead;

{исключение из стека и уничтожение элемента}

StackHead:= StackHead^.NextElem;

dispose( ServiceVar )

end

end;

begin

reset( t );

CreateStack( S );

while not eof( t ) do begin

read(t, c);

{обработка очередной литеры текста (литеры ╚(╩ и ╚,╩ игнорируются)}

if c in ['0'..'9','M','m'] then IncludeInStack( S, c)

else

if c= ')' then begin {конец формулы вида p(x, y)}

{в конце стека находится тройка op x y, она удаляется

из стека, выполняется операция op и результат

записывается в стек}

SelectFromStack( S, y );

SelectFromStack( S, x );

SelectFromStack( S, op );

case op of

'M'{max}: if x > y then c:= x else c:= y;

'm'{min}: if x < y then c:= x else c:= y

end;

IncludeInStack( S, c )

end

end; {of while}

{в стеке осталась одна цифра √ значение всей формулы; цифра переводится в целое число}

SelectFromStack( S, c );

formula:= ord( c ) - ord( '0' )

end;

begin

assign( Source, 'c:tempsource.txt' );

writeln( Formula( Source ) );

end.


Информация о работе «Ссылочные типы. Динамические переменные»
Раздел: Информатика, программирование
Количество знаков с пробелами: 37264
Количество таблиц: 2
Количество изображений: 8

Похожие работы

Скачать
10828
0
0

... ссылочного типа:  <задание ссылочного типа>::= ^<имя типа> ^ - признак ссылочного типа; <имя типа> - имя стандартного либо описанного ранее типа. Это тип динамических объектов, которые может представлять переменная ссылочного типа. Надо подчеркнуть , что здесь может быть только имя типа.  Сами переменные ссылочного типа вводятся обычным образом. type массив = array ...

Скачать
274963
85
0

... ячейка, а имя переменной превращается в адрес ячейки. Появление этого адреса происходит в результате работы специального оператора языка (NEW), однако его значение в большинстве случаев не используется при программировании на алгоритмических языках типа Паскаль. Условимся считать, что адрес ячейки, которая будет хранить переменную А, есть А. Или, другими словами, А - это общее имя переменной и ...

Скачать
94620
8
0

... Закрыть программу можно нажатием на кнопку «Закрыть» или F10. Заключение В квалификационной работе мы попытались раскрыть более полно и наглядно понятие линейного списка, однонаправленного и двунаправленного списков, стека, дека и очереди. Сформировать и закрепить познавательный интерес к данной теме у учащихся. Выявлять и развивать творческие способности в использовании полученного навыка при ...

Скачать
19204
5
5

... "nсреднее целое равно " << MidInt / double(NMax) << "n"; cout << "среднее вещественное равно: " << MidReal / n << "n"; fclose(t); } Списки Обсудим вопрос о том, как в динамической памяти можно создать структуру данных переменного размера. Разберем следующий пример. В процессе физического эксперимента многократно снимаются показания прибора (допустим, термометра) ...

0 комментариев


Наверх