Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
metodichka_po_Pascal_2_chast.doc
Скачиваний:
107
Добавлен:
18.02.2016
Размер:
5.11 Mб
Скачать

Стек, очередь, дек

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

Линейные списки

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

Стек Очередь Дек

(Stack) (Queue) (DEQ)

Стек — это линейный список с переменной длиной, в котором все операции вставки, удаления и доступа к данным выполняются только на одном из концов списка, называемом вершиной стека.

Применяются и другие названия стека — магазин и очередь, функционирующая по принципу LIFO (Last-In-First-Out - "последним пришел — первым исключается"). Системы программирования для блочно-ориентированных языков (Pascal, С и др.) используют стек для размещения в нем локальных переменных процедур и иных программных блоков. При каждой активизации процедуры память для ее локальных переменных выделяется в стеке; при завершении процедуры эта память освобождается. Поскольку при вызовах процедур всегда строго соблюдается вложенность, то в вершине стека всегда находится память, содержащая локальные переменные активной в данный момент процедуры.

Очередь — это такой линейный список с переменной длиной, в котором включение элементов выполняется только с одной стороны списка (эту сторону часто называют концом или хвостом очереди), а исключение — с другой стороны (называемой началом или головой очереди).

Очереди также называют «списками типа FIFO» (First - In - First- Out - «первым пришел — первым исключается»).

В исходном состоянии указатели на начало и на конец указывают на начало области памяти. Равенство этих двух указателей (при любом их значении) является признаком пустой очереди.

Дек (от англ. deq - double ended queue, т.е. очередь с двумя концами), представляет собой структуру данных, в которой можно добавлять и удалять элементы с двух сторон.

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

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

Формы записи арифметического выражения:

  1. Инфиксная — запись, в которой знак арифметической операции расположен между операндами (А+В).

  2. Префиксная - форма записи, в которой знак операции предшествует операндам (+АВ).

  3. Постфиксная - запись, в которой знак операции располагается следом за операндами (АВ+).

Примечание: префиксная форма не является зеркальным отображением постфиксной. Например:

(A-B)*(C+D)

*-AB+CD - префиксная запись;

AB-CD+* - постфиксная запись.

Одной из главных причин, лежащих в основе появления языков программирования высокого уровня, явились вычислительные задачи, требующие больших объёмов рутинных вычислений. Поэтому к языкам программирования предъявлялись требования максимального приближения формы записи вычислений к естественному языку математики. В этой связи одной из первых областей системного программирования сформировалось исследование способов выражений. Здесь получены многочисленные результаты, однако наибольшее распространение получил метод трансляции с помощью обратной польской записи (постфиксная форма записи), которую предложил польский математик Я. Лукашевич.

Обратная польская запись обладает рядом замечательных свойств, которые превращают ее в идеальный промежуточный язык при трансляции. Во-первых, вычисление выражения, записанного в обратной польской записи, может проводиться путем однократного просмотра, что является весьма удобным при генерации объектного кода программ. Например, выражение (A+B)*(C+D)-E в постфиксной форме будет иметь вид: AB+CD+*E-; вычисление полученного выражения может быть проверено следующим образом:

№п/п

Анализируемая строка

Действие

0

AB+CD+*E-

r1=A+B

1

r1CD + *E-

r2=C+D

2

r1 r2 * Е -

r1=r1*r2

3

r1 Е -

r1=r1-E

4

r1

Вычисление окончено

Здесь r1, r2 - вспомогательные переменные.

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

Операция

Приоритет

(

0

+, -

1

*, /

2

Стек пуст

0

Просматривается исходная строка символов слева направо, операнды переписываются в выходную строку, а знаки операций заносятся в стек на основе следующих соображений:

  • если очередной символ из исходной строки есть открывающая скобка, то он проталкивается в стек;

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

  • операция выталкивает из стека все операции с большим или равным приоритетом в выходную строку;

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

Процесс получения обратной польской записи выражения (A+B)*(C+D)-E схематично представлен в таблице

Просматриваемый символ

1

2

3

4

5

6

7

8

9

10

11

12

13

Входная строка

(

A

+

B

)

*

(

C

+

D

)

-

E

Состояние стека

(

(

+

(

+

(

*

(

*

(

*

+

(

*

+

(

*

*

-

-

Выходная строка

A

B

+

C

D

+

*

E

-

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