
- •Федеральное агентство по образованию
- •Тема 3. Бинарные деревья 41
- •Тема 4. Графы 66
- •Введение
- •Терминология
- •Классификация структур данных по различным признакам
- •Типовые операции над структурами данных
- •Эффективность алгоритмов. O-обозначения
- •Тема 1. Стеки, очереди, деки
- •Операции над стеком
- •Реализация стека
- •Реализация основных операций над стеком
- •Использование стека для преобразования форм записи выражений.
- •Очередь
- •Операции над очередью
- •Операции над деком
- •Реализация очереди и дека
- •Реализация основных операций над очередью и деком
- •Итератор
- •Лабораторная работа 1. Стеки, очереди, деки
- •Тема 2. Односвязные и двусвязные линейные списки
- •Линейный список
- •Операции над линейным списком
- •Реализация линейного списка в виде односвязной динамической структуры
- •Реализация основных операций над односвязным списком
- •Циклический список
- •Операции над циклическим списком
- •Односвязная реализация циклического списка
- •Реализация основных операций над односвязным циклическим списком
- •Реализация линейного списка в виде двусвязной динамической структуры
- •Реализация основных операций над двусвязным списком
- •Циклический двусвязный список
- •Реализация основных операций над двусвязным циклическим списком
- •Лабораторная работа 2. Односвязные и двусвязные линейные списки
- •Тема 3. Бинарные деревья
- •Основные понятия и определения
- •Построение бинарного дерева
- •Операции над бинарным деревом
- •Реализация бинарного дерева
- •Реализация основных операций над бинарным деревом
- •Дерево выражения
- •Дерево поиска
- •Операции над деревом поиска
- •Реализация дерева поиска
- •Реализация операций над деревом поиска
- •Сбалансированные деревья
- •Включение в сбалансированное дерево
- •Лабораторная работа 3. Бинарные деревья
- •Тема 4.Графы
- •Основные понятия и определения
- •Граф g7
- •Операции над графом
- •Реализация графа
- •Реализация основных операций над ориентированным графом
- •Обход ориентированного графа
- •Вычисление расстояния между узлами ориентированного графа
- •Лабораторная работа 4. Ориентированные графы
- •Библиографический список
Итератор
Итератор – обобщение итерационных методов, имеющихся в большинстве языков программирования. Итераторы позволяют выполнить итерации для произвольных типов данных. Примеры функций итераторов: выдача элементов некоторого множества в произвольном порядке; выдача элементов набора в заданном порядке, например, от меньшего к большему; выдача элементов очереди от начала к концу и т.д.
С помощью итераторов реализуются более сложные операции с абстрактными типами данных, например, вычисление суммы элементов очереди, печать всех элементов очереди, т.е. такие операции, которые нецелесообразно включать в набор операций класса.
Итератор за одно обращение к нему выдает только один результат (например, значение одного элемента очереди). После выдачи элемента работа итератора не заканчивается. Он готов продолжить выдачу элементов, причем все текущие значения локальных переменных сохраняются при следующем обращении к итератору, т.е. вход в итератор осуществляется, как бы минуя его заголовок и начальные установки итератора.
Пример. Суммирование элементов очереди без итератора.
Решение этой задачи требует создания вспомогательной очереди, при удалении элементов из которой можно суммировать значения элементов.
var
sum:tValue;
q,q1:pQueue;// основная и вспомогательная очереди
begin
...
sum:=0;
q1:=q^.Copy;// копирование основной очереди во вспомогательную
while not q1^.Empty do
sum:=sum+q1^.Remove;
q1^.Destroy;
...
end.
Использование итератора позволит избежать потерь по времени и пространству при копировании очереди (или при выполнении других операций, требующих последовательного обращения к элементам структуры).
Итератор включает в себя три операции: 1) инициализация итератора; 2) выдача очередного элемента; 3) проверка, все ли элементы выданы.
Итератор удобно реализовать в виде операций в абстрактном типе данных (например, в очереди). Для этого в секцию protectedописания типаtQueueдобавим новое поле
fItem:pItem;// указатель на элемент очереди
и методы:
procedure IterInit:
function IterDone: Boolean;
functionIterNext:tValue;
Реализация методов итератора:
proceduretQueue.IterInit;// инициализация итератора
begin
fItem:=fHead;
end; // tQueue.IterInit
function tQueue.IterDone: Boolean; // True, если все элементы выданы
begin
IterDone:= fItem = nil;
end; // tQueue.IterDone
function tQueue.IterNext: tValue; // выдача итератором очередного элемента
begin
if not IterDone
then begin
IterNext:=fItem^.Value;
fItem:=fItem^.Next;
end;
end; // tQueue.IterNext
Пример. Суммирование элементов очереди с итератором.
var
sum: tValue;
q : pQueue;
begin
...
sum:=0; q^.IterInit;
while not q^.IterDone do sum:=sum+q^.IterNext;
...
end.
Лабораторная работа 1. Стеки, очереди, деки
Задание
Опишите и реализуйте класс, необходимый для решения задачи, указанной в вашем варианте задания, и реализуйте его методы.
Составьте программу решения задачи с использованием динамической структуры данных, реализованной в виде класса.
В этой и во всех последующих лабораторных работах должны быть выполнены требования, приведённые ниже в рамке.
Описание класса и реализацию его методов разместите в модуле. Для выполнения операций, не включенных в набор операций класса, например вывод элементов структуры, реализуйте и используйте итератор, либо напишите соответствующий метод.
Исходные данные необходимо считывать из файла и вместе с результатами работы помещать в файл результатов.
В программе следует предусмотреть вывод необходимых промежуточных и всехокончательных результатов решения задачи. По окончании работы экземпляры структур очистить и освободить память, занимаемую ими.
Предусмотреть генерацию и обработку исключительных ситуаций, которые могут возникнуть при выполнении операций со структурами данных.
Варианты заданий
Проверить правильность расстановки скобок в арифметическом выражении (допустимы четыре типа скобок: круглые, квадратные, фигурные и угловые). Для слежения за скобками воспользоваться стеком.
Создать стек, каждый элемент которого является совокупностью двух целых значений. Заменить нулевыми все элементы с заданной суммой значений.
Сформировать стек с элементами – строками. Прочитать три нижних элемента стека и поменять местами верхний и нижний элементы.
Сформировать две очереди с фамилиями клиентов. Слить обе очереди в третью, расположив клиентов через одного.
Прочитать из входного файла последовательность слов PopиPush. СловоPushвталкивается в стек и выводится число элементов стека, при чтении словаPopвыполняется операция исключения элемента из стека. При невозможности выполнения операцииPopвывести нужное сообщение и операцию пропустить.
Ввести программу на языке Бейсик, состоящую из произвольного числа расположенных последовательно или вложенных инструкций:
10 FOR x=a TO b STEP c
…
40 NEXTx
и определить правильность вложения циклов. Для каждого цикла выводить сообщение вида: «Цикл по x открыт», «Цикл по x закрыт».
Перевести программу из задания 6 в следующую форму:
10 x=a-c
20 x=x+c
…
50 IF x<b THEN 20
Номер строки перехода, переменная цикла и ее конечное значение сохраняются в стеке и выталкиваются из него при достижении строки со словом NEXT.
Выполнить задание 6 при условии, что один оператор NEXT, содержащий несколько переменных, может завершать одновременно несколько вложенных циклов (например:NEXT z,y,x).
Решить задачу 7 с условием задания 8.
Преобразовать бесскобочное выражение в инфиксной записи в постфиксную. Операнды представляют собой переменные с однобуквенным идентификатором или (и) цифры от 0до9, и в выражении используются только операции «+», «-», «*», «/».
Вычислить значение выражения, записанного в постфиксной форме (требования к операндам – в задании 10).
Преобразовать выражение в инфиксной форме в префиксную (требования к операндам – в задании 10).
Вычислить значение выражения, записанного в префиксной форме (требования к операндам – в задании 10).
Создать очередь с элементами – строками. Исключить из очереди элементы, начинающиеся с буквы A. Вывести длину получившейся очереди и значения ее первого и последнего элементов.
Сформировать две очереди с элементами – фамилиями клиентов. Удалить из второй очереди клиентов, стоящих также и в первой.
Сформировать очередь целых чисел. С использованием дека расположить все элементы очереди в обратном порядке.
Сформировать два дека с фамилиями клиентов. Слить оба дека в третий, расположив клиентов через одного, начиная с конца.
Сформировать дек, каждым элементом которого являются сведения о студенте (фамилия, номер группы, год рождения). Переписать в очередь студентов заданного года рождения.
Создать дек, каждый элемент которого представляет собой совокупность трех вещественных значений. Исключить из дека все элементы, у которых каждое из трёх значений превышает заданное. Вывести длину получившегося дека и значения его первого и последнего элементов.
Сформировать очередь для двух стеков вещественных значений таким образом, чтобы вершина первого стека стала началом очереди, а вершина второго – её концом.
Создать дек целочисленных значений и распределить все его элементы по двум стекам, начиная с последнего элемента.
Сформировать дек целочисленных элементов и преобразовать его таким образом, чтобы первый элемент стал последним, второй – предпоследним и т.д. При преобразовании исключить из дека нулевые элементы.
Создать очередь клиентов и распределить клиентов по двум вспомогательным очередям (через одного).
Создать дек с элементами – фамилиями студентов. Перенести в очередь элементы с фамилиями, начинающимися с букв «А» – «К».
Создать дек с элементами – двумя целочисленными значениями. Подсчитать количество элементов с заданной суммой значений, прочитать пятый и шестой элементы от начала сформированного дека.
Сформировать две очереди с элементами – фамилиями клиентов. Удалить из первой очереди клиентов, стоящих в двух очередях.
Сформировать очередь целых чисел. С использованием стека расположить все элементы очереди в обратном порядке.
Исключить из стека строк три нижних элемента, если в вершине содержится текст «Вершина». В противном случае изменить содержимое трех нижних элементов на «Первый», «Второй», «Третий».
Сформировать дек, каждым элементом которого являются сведения о студенте (фамилия, номер группы, год рождения). Переписать в очередь студентов заданной группы.
Определить, имеет ли вводимая строка вид xCy, гдеx– строка, состоящая из буквAиB, аy– строка, обратная строкеx. Если да, тоопределить, имеет ли вводимая строка форму aDbD...Dz, где a, b, ..., z – строки вида xCy.
Пример выполнения задания
Описать и реализовать в модуле LineStrs(линейные структуры) класс – стек. Сформировать стек из вещественных элементов, записанных в файлеLW3Dat.txt. Исключить из стека элементы с введенным с терминала значением. Результаты работы записать в файлLW3Res.txt.
Программа решения задачи:
// Лабораторная работа 1. Стеки, очереди, деки.
// Выполнил Сергеев Андрей, группа 500.
// Формирование стека и исключение заданных элементов.
// Исходные данные - элементы стека - в файле LW1Dat.txt
// Результаты работы помещаются в файл LW1Res.txt
programLW1;
uses
SysUtils,
Stacks in 'Stacks.pas';
function WinDOS(const s:string):string;
// Перекодировка русских символов строки s из ANSI (Windows) в ASCII (DOS)
var
i:Word;
begin
Result:=s;// копирование исходной Windows-строки в строку-результат
for i:=1 to Length(s) do begin
case Result[i] of
'А'..'п' : Dec(Result[i],64); // уменьшение кода ANSI на 64
'р'..'я' : Dec(Result[i],16); // уменьшение кода ANSI на 16
'Ё' :Inc(Result[i],72);// увеличение кода ANSI на 72
'ё' : Inc(Result[i],57);// увеличение кода ANSI на 57
end; // case
end; // for
end; // WinDOS
var
Stack1, Stack2:tStack;// основной и вспомогательный стеки
fDat, fRes : Text; // файлы исходных данных и результатов
StVal, DelVal : tValue;// значения текущего и исключаемого элемента
quan : Word;// количество элементов стека
begin
try
Assign(fDat, 'LW1Dat.txt'); Reset(fDat);
Assign(fRes,' LW1Res.txt'); Rewrite(fRes);
// Вывод заголовков в файл результатов
WriteLn(fRes, 'Работа со стеком - поиск и удаление заданного элемента');
// Создание экземпляров Stack1, Stack2 класса tStack
Stack1 := tStack.Create; Stack2 := tStack.Create;
// Формирование стека 1
while not eof(fDat) do begin
Read(fDat, StVal); Stack1.Push(StVal);
end;
quan:=Stack1.Size;
// Вывод элементов стека 1 в файл результатов с помощью итератора
WriteLn(fRes, 'Сформирован стек из ',quan,' элементов:');
Stack1.IterInit;
while not Stack1.IterDone do Write(fRes, Stack1.IterNext:5:1);
Write(WinDos('Значение исключаемого элемента?'));
ReadLn(DelVal);
WriteLn(fRes);
WriteLn(fRes, 'Значение исключаемого элемента = ',DelVal:5:1);
// Исключение элементов из стека 1 и включение не равных DelVal в стек 2
while not Stack1.Empty do begin
StVal:= Stack1.Pop;
if StVal <> DelVal
then Stack2.Push(StVal);
end;
// Перезапись оставшихся после удаления элементов из стека 2 в стек 1
while not Stack2.Empty do begin
StVal:= Stack2.Pop; Stack1.Push(StVal);
end;
// Вывод элементов стека 1 в файл результатов с помощью итератора
WriteLn(fRes, 'Из стека исключено ',quan-Stack1.Size, ' элементов');
WriteLn(fRes, 'В стеке осталось ',Stack1.Size,' элементов:');
Stack1.IterInit;
while not Stack1.IterDone do Write(fRes, Stack1.IterNext:5:1);
WriteLn(fRes);
Stack1.Free; Stack2.Free;
finally
Close(fDat); Close(fRes);
end;
end.