- •Часть 1. Курс лекций
- •Введение.
- •Цели освоения дисциплины
- •Место дисциплины в структуре ооп впо
- •Компетенции обучающегося, формируемые в результате освоения дисциплины (модуля)
- •Тема 1. Алгоритмы на графах (6 часов).
- •Лекция 1. Начальные понятия теории графов.
- •Определение графа
- •Графы и бинарные отношения
- •Откуда берутся графы
- •Число графов
- •Смежность, инцидентность, степени
- •Некоторые специальные графы
- •Графы и матрицы
- •Взвешенные графы
- •Изоморфизм
- •Инварианты
- •Операции над графами
- •Локальные операции
- •Подграфы
- •Алгебраические операции
- •Лекция 2. Поиск в глубину и ширину. Поиск в ширину
- •Процедура поиска в ширину
- •Процедура поиска в глубину
- •Глубинная нумерация
- •Построение каркаса
- •Шарниры
- •Маршруты, пути, циклы
- •Связность и компоненты
- •Метрические характеристики графов
- •Маршруты и связность в орграфах
- •Эйлеровы пути и циклы
- •Построение эйлерова цикла
- •Гамильтоновы пути и циклы
- •Тема 2. Алгоритмы комбинаторного перебора (6 часов).
- •Размещения с повторениями
- •Перестановки
- •Подмножества
- •Разбиения
- •Лекция 5. Коды Грея. Коды Грея и аналогичные задачи
- •Лекция 6. Применение методов комбинаторного перебора.
- •Подсчет количеств
- •Тема 3. Общие методы разработки алгоритмов (6 часов).
- •Ферзи, не бьющие друг друга: обход дерева позиций
- •Лекция 8. Рекурсия. Примеры рекурсивных программ
- •Рекурсивная обработка деревьев
- •Лекция 9. Построение итеративных алгоритмов по рекурсивным.
- •Стек отложенных заданий
- •Более сложные случаи рекурсии
- •Библиографический список
- •Содержание
- •Тема 1. Алгоритмы на графах. 6
- •Тема 2. Алгоритмы комбинаторного перебора. 48
- •Тема 3. Общие методы разработки алгоритмов. 66
- •Шутов Антон Владимирович Медведев Юрий Алексеевич
- •600014, Г. Владимир, ул. Университетская, 2, тел. 33-87-40
Стек отложенных заданий
Другой прием устранения рекурсии продемонстрируем на примере задачи о ханойских башнях.
Написать нерекурсивную программу для нахождения последовательности перемещений колец в задаче о ханойских башнях.
Решение. Вспомним рекурсивную программу, перекладывающую i верхних колец с m на n:
procedure move(i,m,n: integer);
| var s: integer;
begin
| if i = 1 then begin
| | writeln ('сделать ход ', m, '->', n);
| end else begin
| | s:=6-m-n; {s - третий стержень: сумма номеров равна 6}
| | move (i-1, m, s);
| | writeln ('сделать ход ', m, '->', n);
| | move (i-1, s, n);
| end;
end;
Видно, что задача "переложить i верхних дисков с m -го стержня на n -ый" сводится к трем задачам того же типа: двум задачам с i-1 дисками и к одной задаче с единственным диском. Занимаясь этими задачами, важно не позабыть, что еще осталось сделать.
Для этой цели заведем стек отложенных заданий, элементами которого будут тройки . Каждая такая тройка интерпретируется как заказ "переложить i верхних дисков с m -го стержня на n -ый". Заказы упорядочены в соответствии с требуемым порядком их выполнения: самый срочный - вершина стека. Получаем такую программу:
procedure move(i,m,n: integer);
begin
| сделать стек заказов пустым
| положить в стек тройку <i,m,n>
| {инвариант: осталось выполнить заказы в стеке}
| while стек непуст do begin
| | удалить верхний элемент, переложив его в <j,p,q>
| | if j = 1 then begin
| | | writeln ('сделать ход', p, '->', q);
| | end else begin
| | | s:=6-p-q;
| | | {s - третий стержень: сумма номеров равна 6}
| | | положить в стек тройки <j-1,s,q>, <1,p,q>, <j-1,p,s>
| | end;
| end;
end;
(Заметим, что первой в стек кладется тройка, которую надо выполнять последней.) Стек троек может быть реализован как три отдельных стека. (Кроме того, в паскале есть специальный тип, называемый "запись" ( record ), который может быть применен.)
Для задачи о ханойских башнях есть и другие нерекурсивные алгоритмы. Вот один из них: простаивающим стержнем (не тем, с которого переносят, и не тем, на который переносят) должны быть все стержни по очереди. Другое правило: поочередно перемещать наименьшее кольцо и не наименьшее кольцо, причем наименьшее - по кругу.
Написать нерекурсивный вариант программы быстрой сортировки. Как обойтись стеком, глубина которого ограничена , где - число сортируемых элементов?
Решение. В стек кладутся пары , интерпретируемые как отложенные задания на сортировку соответствующих участков массива. Все эти заказы не пересекаются, поэтому размер стека не может превысить . Чтобы ограничиться стеком логарифмической глубины, будем придерживаться такого правила: глубже в стек помещать больший из возникающих двух заказов. Пусть - максимальная глубина стека, которая может встретиться при сортировке массива из не более чем элементов таким способом. Оценим сверху таким способом: после разбиения массива на два участка мы сначала сортируем более короткий (храня в стеке более длинный про запас), при этом глубина стека не больше , затем сортируем более длинный, так что
откуда очевидной индукцией получаем .