![](/user_photo/1334_ivfwg.png)
- •Министерство образования Российской Федерации
- •Содержание
- •1.2 Скорость роста функций
- •1.3 Анализ алгоритмов; время работы в лучшем, худшем случаях и в среднем
- •1.4 Типы данных, структуры данных и абстрактные типы данных
- •1.5 Динамические множества
- •2 Алгоритмы сортировок
- •2.1 Понятие внутренней и внешней сортировки
- •2.2 Сортировка вставками
- •2.3 Сортировка слиянием
- •2.3.1 Описание алгоритма
- •2.3.2 Анализ времени работы алгоритмов «разделяй и властвуй»
- •2.3.2 Анализ времени работы сортировки слиянием через рекуррентное соотношение
- •2.3.3 Анализ времени работы сортировки слиянием через геометрическую интерпретацию
- •2.4 Пирамидальная сортировка
- •2.4.1 Введение в алгоритм
- •2.4.2 Сохранение основного свойства кучи
- •2.4.3 Построение кучи
- •2.5 Быстрая сортировка
- •2.5.1 Введение в алгоритм
- •2.5.2 Описание
- •2.5.3 Разбиение массива
- •2.5.4 Особенности работы быстрой сортировки
- •2.6 Особенности реализации алгоритмов сортировки; сортировка за линейное время
- •2.6.1 Введение
- •2.6.2 Разрешающее дерево сортировки сравнениями
- •2.7 Цифровая сортировка
- •2.8 Сортировка вычерпыванием
- •2.8.1 Описание алгоритма
- •2.8.2 Вероятностный анализ времени работы сортировки вычерпыванием
- •2.8.3 Анализ времени работы сортировки вычерпыванием через геометрическую интерпретацию
- •2.9 Сортировка подсчетом
- •2.9.1 Описание алгоритма
- •2.9.2 Анализ времени работы
- •3 Элементарные и нелинейные структуры данных
- •3.1 Элементарные структуры: список, стек, очередь, дек
- •3.1.1 Список Линейный однонаправленный список
- •Линейный двунаправленный список
- •Двунаправленный список с фиктивными элементами
- •Циклические списки
- •Циклический однонаправленный список
- •Циклический двунаправленный список
- •3.1.2 Стек
- •3.1.3 Очередь
- •3.1.3 Дек
- •3.2 Нелинейные структуры данных
- •3.2.1 Представление корневых деревьев в эвм
- •Обходы деревьев
- •3.2.2 Двоичные деревья Спецификация двоичных деревьев
- •Реализация
- •Обходы двоичных деревьев
- •3.2.3 Двоичные деревья поиска Основные операции
- •Минимум и максимум
- •Следующий и предыдущий элементы
- •Добавление и удаление
- •Случайные деревья поиска
- •Оптимальные деревья поиска
- •4 Хеширование
- •4.1 Введение
- •4.2 Прямая адресация; таблицы с прямой адресацией
- •4.3 Хеш – таблицы; возникновение коллизий и их разрешение
- •Разрешение коллизий с помощью цепочек
- •Анализ хеширования с цепочками
- •4.4 Способы построения хеш – функций Выбор хорошей хеш-функции
- •Ключи как натуральные числа
- •Деление с остатком
- •Умножение
- •Универсальное хеширование
- •4.5 Открытая адресация; способы вычисления последовательности испробованных мест: линейная последовательность проб, квадратичная последовательность проб, двойное хеширование
- •Линейная последовательность проб
- •1 / (1 – )
- •5 Основные принципы разработки алгоритмов
- •5.1 Введение в теорию графов
- •5.1.1 Графы
- •5.1.2 Представление графов
- •5.2 Алгоритмы на графах: поиск в ширину, поиск в глубину
- •5.2.1 Поиск в ширину (волновой алгоритм)
- •5.2.2 Анализ поиска в ширину
- •5.2.3 Деревья поиска в ширину
- •5.2.4 Поиск в глубину
- •5.2.5 Анализ поиска в глубину
- •5.2.6 Свойства поиска в глубину
- •5.2.7 Классификация рёбер
- •5.3 Топологическая сортировка, задача о разбиении графа на сильно связанные компоненты
- •5.3.1 Топологическая сортировка
- •5.3.2 Сильно связные компоненты
- •5.4 Алгоритм построения минимального остовного дерева
- •5.4.1 Остовные деревья минимальной стоимости
- •5.4.2 Построение минимального покрывающего дерева
- •5.4.3 Алгоритмы Крускала и Пpимa
- •5.4.4 Алгоритм Крускала
- •5.4.5 Алгоритм Прима
- •5.5 Задача нахождения кратчайших путей на графах; алгоритм Флойда; алгоритм Дейкстры
- •5.5.1 Нахождение кратчайшего пути
- •5.5.2 Алгоритм Дейкстры
- •5.5.3 Алгоритм Флойда
- •5.6 Поиск с возвратом
- •5.6.1 Введение
- •5.6.2 Переборные алгоритмы
- •5.6.3 Метод ветвей и границ
- •5.6.4 Метод альфа-бета отсечения
- •5.6.5 Локальные и глобальные оптимальные решения
- •5.7 Метод декомпозиции ( «Разделяй и властвуй»)
- •5.7.1 «Ханойские башни»
- •5.8 Жадные алгоритмы и динамическое программирование
- •5.8.1 Задача о выборе заявок
- •5.8.2 Дискретная задача о рюкзаке
- •5.8.3 Непрерывная задача о рюкзаке
- •5.8.4 Числа Фибоначчи
- •5.8.5 Задача триангуляции многоугольника
- •5.8.6 Дп, жадный алгоритм или что-то другое?
5.2.5 Анализ поиска в глубину
Подсчитаем
общее
число
операций
при
выполнении
процедуры
DFS.
Цик-
лы
в
строках
1
–
3 и
5
–
7
требуют
(V)
времени
(помимо
вызовов
DFS-VISIT).
Процедура
DFS-VISIT
вызывается
ровно один
раз
для
каждой
вершины
(ей
передаётся
белая
вершина,
и
она
сразу
же
делает
её
серой). Во
время
выполнения
DFS-VISIT(v)
цикл
в
строках
3
–
6
выполняется
|Adj[v]|
раз.
Поскольку
общее
время
выполнения
строк
3 – 6
процедуры
DFS-VISIT
составляет
(Е).
В сумме
получается
время
(V + E).
Проще можно сказать и так: поиск в глубину для полного обхода графа с n вершинами и m дугами требует общего времени порядка O(max(n, m)). Поскольку обычно m n, то получается O(m).
5.2.6 Свойства поиска в глубину
Прежде
всего
отметим,
что
подграф
предшествования
(составленный
из
деревьев
поиска в
глубину)
в
точности
соответствует
структуре
рекурсивных
вызовов
процедуры DFS-VISIT.
Именно,
u
=
[v]
тогда
и
только
тогда,
когда
произошёл
вызов
DFS-VISIT(v)
во
время
просмотра
списка
смежных
с
и
вершин.
Другое важное свойство состоит в том, что времена обнаружения и окон- чания обработки образуют правильную скобочную структуру (parenthesis struc- ture). Будем обозначать обнаружение вершины и открывающейся скобкой с пометкой и, а окончание её обработки закрывающейся с тои же пометкой. Тогда перечень событий будет правильно построенным выражением из скобок (парные скобки имеют одинаковые пометки). Например, поиску в глубину на рис. 5.3(а) соответствует расстановка скобок, изображённая на рис. 5.3(б).
Чтобы доказать эти и другие свойства, мы должны рассуждать по индук- ции. При этом, доказывая требуемое свойство рекурсивной процедуры DFS-- VISIT, мы предполагаем, что рекурсивные вызовы этой процедуры обладают выбранным свойством.
Убедимся вначале, что вызов DFS-VISIT(u) для белой вершины и делает чёрной эту вершину и все белые вершины, доступные из неё по белым путям (в которых все промежуточные вершины также белые), и оставляет серые и чёрные вершины без изменений.
В самом деле, рекурсивные вызовы в строке 6 выполняются лишь для белых вершин, являющихся смежными с и. Если какая-то вершина w была закрашена в ходе этих вызовов, то (по индуктивному предположению) она была доступна по белому пути из одной из белых вершин, смежных с и, и потому доступна по белому пути из и.
Напротив, если вершина w доступна по белому пути из и, то она доступна по белому пути из какой-то белой вершины v, смежной с и (посмотрим на первый шаг пути). Будем считать, что v первая из таких вершин (в порядке просмотра в строке 3). В этом случае все вершины белого пути из v в w останутся белыми к моменту вызова DFS-VISIT(v), поскольку они недоступны по белым путям из предшествующих v вершин (иначе w была бы также доступна). По индуктивному предположению w станет чёрной после вызова DFS-VISIT(v).
Кроме того, сама вершина и станет сначала серой, а потом чёрной. (За- метим, что мы могли бы сразу сделать её чёрной, и программа осталась бы правильной, так как она никак не различает серые и чёрные вершины, однако различие между серым и чёрным нам пригодится в дальнейшем.)
Рисунок 5.3 – Свойства поиска в глубину
На рис. 5.3 изображены: (а) Результат поиска. (б) Промежутки между обнаружением и окончанием обработки для каждой из вершин, изображённые в виде прямоугольников. Стрелки указывают структуру деревьев поиска в глубину. (в) Отмечены рёбра исходного графа с указанием их типов (рёбра дерева и прямые рёбра ведут вниз, обратные ведут вверх).
Ясно также, что цвета серых и чёрных вершин остаются без изменений (поскольку это верно для рекурсивных вызовов по индуктивному предположе- нию).
Аналогичные
рассуждения
по
индукции
позволяют
установить,
что
вызов
DFS‑VISIT(u)
меняет поля
[v]
для
всех
окрашиваемых
вершин
v,
отличных
от
и,
тем
самым
формируя
из
них дерево
с
корнем
в
и,
а
также
добавляет
к
описанному
выше
протоколу
из
скобок
с
пометками правильное
скобочное
выражение,
внешние
скобки
которого
имеют
пометку
и,
а
внутри находятся
скобки
с
пометками,
соответствующими
окрашиваемым
вершинам.
Подводя итоги, можно сформулировать следующие утверждения.
Теорема 5.2 (о скобочной структуре). При поиске в глубину в ориентирован- ном или неориентированном графе G = (V, Е) для любых двух вершин u и v выполняется ровно одно из следующих трёх утверждений:
отрезки [d[u], f [u]] и [d[v], f[v]] не пересекаются;
отрезок [d[u],f[u]] целиком содержится внутри отрезка [d[v],f[v]] и u – потомок v в дереве поиска в глубину;
отрезок [d[v], f[v]] целиком содержится внутри отрезка [d[u], f[u]] и v – потомок и в дереве поиска в глубину.
Следствие 5.3 (вложение интервалов для потомков). Вершина v является (от- личным от u) потомком вершины и в лесе поиска в глубину для (ориентирован- ного или неориентированного) графа G, если и только если d[u] < d[v] < f [v] < f[u].
Теорема 5.4 (о белом пути). Вершина v является потомком вершины u в лесе поиска в глубину (для ориентированного или неориентированного графа G = (V, Е)) в том и только том случае, если в момент времени d[u], когда вершина u обнаружена, существует путь из u в v, состоящий только из белых вершин.