- •Содержание
- •Введение
- •Структуры данных Классификация структур данных
- •Операции над данными
- •Понятие алгоритма
- •Массивы Описание массива
- •Представление массивов в памяти
- •Рис 1. Представление вектора в памяти
- •Рис 2. Представление вектора ml в памяти
- •Алгоритмы поиска
- •Алгоритмы сортировки
- •Пример сортировки простыми вставками.
- •Описание записи
- •Операции над записями
- •Записи с вариантами
- •Представление записи в памяти
- •Общие процедуры и функции для работы с файлами
- •Процедуры и функции для работы с типизированными файлами.
- •Сортировка содержимого файлов (Внешняя сортировка)
- •Пример внешней сортировки прямым слиянием
- •Пример внешней сортировки естественным слиянием
- •Динамическая память и данные с динамической структурой
- •Ссылочный тип в языке Pascal
- •Типизированные указатели
- •Нетипизированные указатели
- •Операции над переменными ссылочного типа.
- •Динамические списки
- •Реализация списков на языке Pascal.
- •Стек, очередь, дек
- •Рекурсия
- •Нелинейные структуры данных. Деревья
- •Бинарные деревья
- •Реализация бинарных деревьев
- •Способы обхода бинарных деревьев
- •Сортировка с прохождением бинарного дерева
Стек, очередь, дек
На базе линейных списков могут строиться стеки, очереди, деки.
Линейные списки
(по способу выполнения операции добавления и удаления элементов)
Стек Очередь Дек
(Stack) (Queue) (DEQ)
Стек — это линейный список с переменной длиной, в котором все операции вставки, удаления и доступа к данным выполняются только на одном из концов списка, называемом вершиной стека.
Применяются и другие названия стека — магазин и очередь, функционирующая по принципу LIFO (Last-In-First-Out - "последним пришел — первым исключается"). Системы программирования для блочно-ориентированных языков (Pascal, С и др.) используют стек для размещения в нем локальных переменных процедур и иных программных блоков. При каждой активизации процедуры память для ее локальных переменных выделяется в стеке; при завершении процедуры эта память освобождается. Поскольку при вызовах процедур всегда строго соблюдается вложенность, то в вершине стека всегда находится память, содержащая локальные переменные активной в данный момент процедуры.
Очередь — это такой линейный список с переменной длиной, в котором включение элементов выполняется только с одной стороны списка (эту сторону часто называют концом или хвостом очереди), а исключение — с другой стороны (называемой началом или головой очереди).
Очереди также называют «списками типа FIFO» (First - In - First- Out - «первым пришел — первым исключается»).
В исходном состоянии указатели на начало и на конец указывают на начало области памяти. Равенство этих двух указателей (при любом их значении) является признаком пустой очереди.
Дек (от англ. deq - double ended queue, т.е. очередь с двумя концами), представляет собой структуру данных, в которой можно добавлять и удалять элементы с двух сторон.
Задачи, требующие структуры дека, встречаются в вычислительной технике и программировании гораздо реже, чем задачи, реализуемые на структуре стека или очереди. Как правило, вся организация дека выполняется программистом без каких-либо специальных средств системной поддержки.
Примером дека может быть, например, некий терминал, в который вводятся команды, каждая из которых выполняется какое-то время. Если ввести следующую команду, не дождавшись, пока закончится выполнение предыдущей, то она встанет в очередь и начнет выполняться, как только освободится терминал. Это FIFO очередь. Если же дополнительно ввести операцию отмены последней введенной команды, то получается дек.
Формы записи арифметического выражения:
Инфиксная — запись, в которой знак арифметической операции расположен между операндами (А+В).
Префиксная - форма записи, в которой знак операции предшествует операндам (+АВ).
Постфиксная - запись, в которой знак операции располагается следом за операндами (АВ+).
Примечание: префиксная форма не является зеркальным отображением постфиксной. Например:
(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 |
- |