
- •Программирование и алгоритмические языки. Курс за второй семестр. Абстрактные типы данных.
- •Задача раскраски.
- •Перечисление последовательностей фиксированной длины.
- •Два взгляда на диаграммы – графы и автоматы.
- •А нглия
- •Деревья
- •Словарный порядок на последовательностях произвольной длины
- •Статическая реализация стеков.
- •Очереди. Статическая реализация.
- •Статическая реализация деревьев.
- •Автоматы как структуры данных
- •Статическая реализация графов. Проблема фрагментации памяти. Списочные структуры.
- •Общая схема реализации автомата как списка.
- •Обработка кучи.
- •Динамическая реализация абстрактных типов ссылками. Ссылочные типы Паскаля.
- •Ссылочные типы Паскаля. Синтаксис типов.
- •Объявление списочной структуры в Паскале.
- •Реализация стеков.
- •Реализация очередей.
- •Основные операции над стеками.
- •Обработка деревьев. Деревья выражений.
- •Поиск атома.
- •Различные объединения типов. Записи типов с вариантами.
- •Создание дерева. Перевод из префиксной записи. Представление записи.
- •Анализ алгоритма вычисления. Дерево как последовательность ветвей.
- •Задача синтаксического анализа.
- •Графы-выражения.
- •Раздельное описание абстрактных типов. Модульное программирование.
- •Проблема с кратным использованием модулей.
- •Деревья как структуры данных.
- •Деревья поиска.
- •Включение в дерево поиска.
- •Другие обходы дерева. Обход в ширину.
- •Рекурсивные процедуры и функции. Примеры применения.
- •Поиск в дереве.
- •Проблемы с семантикой рекурсии.
- •Введение в машинно-ориентированное (ссылочное) программирование.
- •Создание новых структурных операторов.
- •Формальная семантика goto и неструктурных программ.
- •Мини-Паскаль.
- •Представление сложных типов. Адресная арифметика.
- •Проблемы реализации ввода-вывода. Идея буферизации.
- •Реализация процедур read и write.
- •Реализация структур управления.
- •Путь наверх. Реализация процедур-подпрограмм.
- •Передача параметров.
- •Сохранение и восстановление значений. Соглашение о связях.
- •Введение в теоретическое программирование. Границы программирования. Принципиальная и практическая неразрешимость.
- •О формальной спецификации. Мир задачи как автомат.
- •Процедуры как функции на множестве состояний. Процедуры как преобразователи предикатов.
- •Универсальные методы решения задач.
Словарный порядок на последовательностях произвольной длины
c1…ck c1|…c|L, т.е. i0 (ci0ci0| & ii0 (ci=c|I) or (i (ci=ci|) and k<L)
Технический приём: дополнить меньшее слово фиктивным элементом, например пробелом, наименьшим по определению.
Можно:=false;
Раскраска:=Первая раскраска; {<первый цвет>}
While (не кончилась раскраска) do begin
{Пустая раскраска – последовательность длины 0}
If правильная (раскраска) then if полная (раскраска) then begin
Можно:=true {печать (раскраска)}
Else {раскраска правильная, но не полная}
{дополнить} раскраска:=раскраска + первый цвет
else {возврат} раскраска:=succ(раскраска);
Переход к следующей раскраске при новом определении словарного порядка:
Выбрасывать все последние значения с конца последовательности до тех пор, пока не выкинем первый элемент, у которого есть следующий. Если такого нет, то раскраска кончилась.
Если раскраски не кончились, возвратить следующий за последним, выкинутым в раскраску.
Последовательность, из конца которой можно выкидывать и в конец которой можно добавлять элементы, называется стеком (stack).
Стеком называется абстрактный тип данных, множеством значений которого является множество всех последовательностей произвольной длины (динамический тип) элементов некоторого базового типа Т со следующими операциями:
Push ([x:tStack], y:T), х – имя стека – затолкнуть y в стек.
Семантика: x:=x+y (добавление элементов в конец последовательности)
Pop ([x:tStack]):T
If x=c1…cn then pop=cn. Длина стека уменьшается на 1: x=c1…cn-1.
Попытка взять элемент из пустого стека считается ошибкой.
Empty ([x:tStack]):boolean; – стек пуст.
If Empty([x:tStack]){=true} then {длина стека равна нулю}.
Характерные для динамических типов операции Create([x:tStack]) и Destroy([x:tStack]) рассмотрим позднее.
Стеки также называют «магазинной» памятью.
Переход к следующей раскраске, если такой нет, то к пустой.
Procedure Новая (var раскраска:tStack);
Var x:tЦвет;
Begin
Pop(stack,x);
while not empty(stack) and (x=последний цвет) do pop(stack,x);
if not empty(stack) then push(succ(x));
End;
Дополнить раскраску=push(stack,первый цвет)
Кончились раскраски – empty(stack)
Упражнение. Завершить реализацию перебора с возвратом, написав процедуру «Правильная».
c1…ck+1 – правильная, то c1…сk – правильная.
i[1,k] (соседи(ck,ck+1))
раскраска(1)раскраска(k+1)
(Выходим за пределы стековых операций).
Статическая реализация стеков.
Стек – динамический тип данных – количество элементов, которое можно положить в стек, не ограничено (в идеале), но во многих случаях, в том числе в задаче о раскраске карты, известна максимальная глубина стека, то есть стек можно понимать статически. Стандартный приём оперировать с такими типами (абстрактными, но статическими) – моделировать их массивами и переменными стандартных типов.
top heap
nMax
|
Куча |
Type index=1..nMax{ };
T={базовый тип стека};
TStack= record
content:array[index] of T;
heap:index;{указатель на начало «кучи», первую свободную компоненту массива}
end;
procedure push(var stack:tStack;x:T);
begin
with Stack do
begin
content[heap]:=x;
inc(heap);
end;
end;
Реализация не защищена от ошибки – переполнения стека. Предполагается, что ситуацию контролирует пользователь.
Procedure Pop(stack:tStack;var x:T);
Begin
with stack do
begin
dec(heap);
x:=content[heap];
end;
end;
Снова незащищённая реализация: контроль за пустотой стека возлагается на пользователя.
Function Empty(stack:tStack):boolean;
Begin
empty:=stack.heap=1;
end;
Procedure Init(stack:tStack);{инициализация стека}
Begin
stack.heap:=1;
end;