- •Программирование и алгоритмические языки. Курс за второй семестр. Абстрактные типы данных.
- •Задача о раскраске.
- •Перечисление последовательностей фиксированной длины.
- •Var I:tСтраны; c:tЦвет;
- •Два взгляда на диаграммы – графы и автоматы.
- •Деревья
- •Как сократить перебор с возвратом. Перечисление последовательностей переменной длины
- •Словарный порядок на последовательностях произвольной длины
- •Статическая реализация стеков.
- •Очереди. Статическая реализация.
- •Статическая реализация деревьев.
- •Автоматы как структуры данных
- •Статическая реализация графов. Проблема фрагментации памяти. Списочные структуры.
- •Общая схема реализации автомата как списка.
- •Обработка кучи.
- •Динамическая реализация абстрактных типов ссылками. Ссылочные типы Паскаля.
- •Ссылочные типы Паскаля. Синтаксис типов.
- •Объявление списочной структуры в Паскале.
- •Реализация стеков.
- •Реализация очередей.
- •Основные операции над списками.
- •Обработка деревьев. Деревья выражений.
- •Поиск атома.
- •Различные объединения типов. Записи типов с вариантами.
- •Создание дерева. Перевод из префиксной записи. Представление записи.
- •Анализ алгоритма вычисления. Дерево как последовательность ветвей.
- •Задача синтаксического анализа.
- •Графы-выражения.
- •Раздельное описание абстрактных типов. Модульное программирование.
- •Проблема с кратным использованием модулей.
- •Деревья как структуры данных.
- •Деревья поиска.
- •Поиск в дереве поиска.
- •Включение в дерево поиска.
- •Другие обходы дерева. Обход в ширину.
- •Рекурсивные процедуры и функции. Примеры применения.
- •Поиск в дереве.
- •Проблемы с семантикой рекурсии.
- •Введение в машинно-ориентированное (ссылочное) программирование. Оператор Goto.
- •Создание новых структурных операторов.
- •Формальная семантика goto и неструктурных программ.
- •Мини-Паскаль.
- •Представление сложных типов. Адресная арифметика.
- •Проблемы реализации ввода-вывода. Идея буферизации.
- •Реализация процедур read и write.
- •Реализация структур управления.
- •Путь наверх. Реализация процедур-подпрограмм.
- •Передача параметров.
- •Сохранение и восстановление значений. Соглашение о связях.
- •Введение в теоретическое программирование. Границы программирования. Принципиальная и практическая неразрешимость.
- •О формальной спецификации. Мир задачи как автомат.
- •Процедуры как функции на множестве состояний. Процедуры как преобразователи предикатов.
- •Универсальные методы решения задач.
Общая схема реализации автомата как списка.
Атрибуты вершин графа.
На каждую стрелку отдельное поле, хранящее указатель на вершину, к которой ведёт эта стрелка.
Светофор
1 2 3 4 5 6 7 8
|
|
К |
|
З |
|
Ж |
|
5 7 3
-
5
type tIndex=1..nMax;
tList=record
content:array[tIndex] of tNode;
head:tIndex;
end;
tNode=record
info:tInfo; {Атрибуты вершины}
next:tIndex;
end;
tGraphNode=record
info:tInfo[tIndex] of tNode;
left,right:tIndex;
end;
Варианты – перечень полей-указателей. Например, для бинарного дерева – left,right:tIndex. Либо массив-указатель, либо список.
Новый способ требует больше памяти. Окупится ли «жертва» эффективной вставки и удаления? Убедимся в этом (оставим на время проблемы, связанные с обработкой кучи).
Задача. Включить в список List компоненту x после компоненты.
procedure Include(var List:tList;x:tInfo;AfterPtr:tIndex);
var NewPtr:tIndex;
begin
{Взять первый свободный индекс NewPtr из кучи}
GetHeap(List,NewPtr); After NewPtr
with List do
-
ai
x
begin
content[NewPtr].next:=content[AfterPtr].next;
content[AfterPtr].next:=NewPtr;
content[NewPtr].info:=x;
end;
end;
Замечание: процедура Include корректно работает, если известна ссылка на предыдущую компоненту, после которой надо вставлять.
Техническая проблема: она не может включать в пустой список. Не хочется писать отдельную процедуру для включения в пустой список. Проверять же непустоту списка в процедуре Include неэффективно.
Решение: расширить тип Index до 0..nMax и при инициализации списка поставить в него фиктивную нулевую компоненту («болванчик» или «фантом»).
procedure Init(List:tList);
begin
with list do
begin
content[0].next:=0;
head:=0;
end;
{Инициализировать кучу}
end;
{Удаление элемента из списка, стоящего после компоненты AfterPtr}
procedure Exclude(var list:tList;AfterPtr:tIndex);
AfterPtr
j
ai+1
j2 ai+2 ai
j1
(удаление)
{Работает в предположении, что удалённая компонента существует}
var ThisPtr:tIndex;
begin
with list do
begin
ThisPtr:=content[AfterPtr].next;
content[AfterPtr].next:=content[ThisPtr].next;
{Сборка мусора – возвратить освободившуюся компоненту в кучу}
PutHeap(List,ThisPtr);
end;
end;