
- •Содержание
- •Введение.
- •1. Основы анализа алгоритмов
- •1.1. Сравнительные оценки алгоритмов
- •1.2. Элементарные операции в формальной системе
- •1.3. Классы входных данных
- •1.4. Классификация алгоритмов по виду функции трудоемкости
- •1.5. Классификация скоростей роста. Асимптотический анализ функций
- •1. Оценка (тета)
- •2. Оценка о (о большое)
- •3. Оценка (Омега)
- •1.6. Эффективность рекурсивных алгоритмов
- •1.7. Анализ программ
- •1.8. Вопросы для самоконтроля
- •Классификация алгоритмов по виду функции трудоемкости.
- •2. Алгоритмы поиска и выборки
- •2.1. Последовательный поиск
- •2.2. Двоичный поиск
- •2.3. Задача выборки
- •2.4. Вопросы для самоконтроля
- •3.Алгоритмы сортировки
- •3.1. Сортировка трех чисел по месту
- •3.2. Сортировка вставками
- •3.3. Пузырьковая сортировка
- •3.4. Сортировка Шелла.
- •3.5. Корневая сортировка
- •3.6. Сортировка методом индексов
- •3.7. Быстрая сортировка (алгоритм Хоара)
- •3.8. Вопросы для самоконтроля
- •Сортировка Шелла.
- •Сортировка методом индексов.
- •4. Алгоритмы на графах
- •4.1. Основные понятия теории графов
- •4.2. Структуры данных для представления графов
- •4.3. Алгоритмы обхода вершин графа
- •4.3.1. Обход в глубину
- •4.3.2. Обход в ширину
- •4.4. Поиск остовного дерева минимального веса
- •4.4.1. Алгоритм Дейкстры – Прима
- •4.4.2. Алгоритм Крускала
- •4.5. Алгоритм поиска кратчайшего пути
- •4.6. Вопросы для самоконтроля
- •Структуры данных для представления графов.
- •5. Численные методы
- •5.1. Вычисление значений многочленов
- •5.2. Умножение матриц
- •5.2.1 Стандартный алгоритм умножения матриц
- •5.2.2. Умножение матриц по Винограду
- •5.2.3. Умножение матриц по Штрассену
- •5.3. Вопросы для самоконтроля
- •Стандартный алгоритм умножения матриц.
- •6. Алгоритмы сравнения с образцами
- •6.1. Сравнение строк
- •6.2. Алгоритм Кнута – Морриса – Пратта
- •6.3. Алгоритм Бойера - Мура
- •6.4. Вопросы для самоконтроля
- •7. Вычислительная геометрия
- •7.1. Основные понятия
- •7.2. Векторное произведение векторов
- •7.2.1. Ориентированная площадь треугольника
- •7 .3. Задача о выпуклой оболочке
- •7.3.1. Алгоритм Грэхема
- •7.3.2. Алгоритм Джарвиса
- •7.3.3. Рекурсивный алгоритм
- •7.4. Вопросы для самоконтроля
- •8. Задачи класса np
- •8.1. Примеры np-полных задач
- •8.1.1. Задача о коммивояжере
- •8.1.2. Задача о раскраске графа
- •8.1.3. Раскладка по ящикам
- •8.1.4 Упаковка рюкзака
- •8.1.5. Задача о суммах элементов подмножества
- •8.1.6. Задача о планировании работ
- •8.2. Приближенные эвристические решения nр-полных задач.
- •8.2.1. Жадные приближенные алгоритмы
- •8.2.2. Приближения в задаче коммивояжера
- •8.2.3. Приближения в задаче о раскладке по ящикам
- •8.2.4. Приближения в задаче об упаковке рюкзака
- •8.3. Вопросы для самопроверки
- •Приближения в задаче об упаковке рюкзака.
- •9. Динамическое программирование
- •Часть1--------------------
- •10. Метод ветвей и границ
- •Вопросы к зачету
- •Классификация алгоритмов по виду функции трудоемкости.
- •Приближения в задаче об упаковке рюкзака.
- •Динамическое программирование
- •Метод ветвей и границ. Литература
2.4. Вопросы для самоконтроля
Алгоритм последовательного поиска. Оценка худшего, лучшего и среднего случая.
Алгоритм двоичного поиска. Оценка среднего случая.
Выборка k-го по величине значения.
Рекурсивный алгоритм выборки k-го по величине значения.
3.Алгоритмы сортировки
Благодаря значительной экономии времени при двоичном поиске по сравнению с последовательным поиском разработчики программного обеспечения нередко предпочитают хранить информацию в отсортированном виде, чтобы поиск нужных данных можно было вести посредством двоичного или других методов, отличных от полного перебора.
Все изучаемые алгоритмы будут сортировать список в порядке возрастания ключа (хотя, если поменять знак ”>” на ”<”, то список окажется отсортированным в порядке убывания.)
3.1. Сортировка трех чисел по месту
На вход поступают три числа. Алгоритм, производящий сортировку, выглядит следующим образом:
SortABC1(a,b,c)
If a>b then // обмен a и b
ta; ab; bt
endif
If b>c then // обмен b и c
tb; bc; ct
endif
If a>b then // обмен a и b
ta; ab; bt
endif
end
Для
этого алгоритма fА1
=12 (набор 3,2,1), fА1
=3 (набор
1,2,3). В среднем случае получаем
fА1-=3+3*
+3*
+3*
=7
.
Допустим, на вход поступают числа 1,2,3. Распишем все возможные комбинации, в которых могут прийти эти числа: (1,2,3), (1,3,2), (2,1,3), (2,3,1), (3,1,2), (3,2,1).
Очевидно, что эти тройки чисел можно разделить на две группы, в одной из которых a>b, в другой a<b. Анализируя их, получаем алгоритм 2:
SortABC2(a,b,c)
If a>b then
If b>c then //ситуация 321, обмен 3 и 1 местами
ta; ac; ct
else
if a>c then // ситуация 312
ta; ab; bc; ct
else // ситуация 213, обмен 2 и 1 местами
ta; ab; bt
endif
endif
else
If b>c then
If a>c then // ситуация 231
tc; cb; ba; at
else // ситуация 132, обмен 3 и 2
tb; bc; ct
end if
else // ситуация 123
exit.
endif
endif
end
Вероятности появления любой комбинации равны между собой, и составляют 1/6. Оценки трудоемкости этого алгоритма соответственно равны:
в лучшем случае fА2 =2, в худшем - fА2=7, в среднем fА2=5 .
3.2. Сортировка вставками
Основная идея сортировки вставками состоит в том, что при добавлении нового элемента в уже отсортированный список его стоит сразу вставить в нужное место, вместо того, чтобы вставлять его в произвольное место, а затем заново сортировать весь список.
Сортировка вставками считает первый элемент любого списка отсортированным списком длины 1. Двухэлементный отсортированный список создается добавлением второго элемента исходного списка в нужное место одноэлементного списка, содержащего первый элемент. Теперь можно вставить третий элемент исходного списка в отсортированный двухэлементный список. Этот процесс повторяется до тех пор, пока все элементы исходного списка не окажутся в расширяющейся отсортированной части списка.
InsertSort (list, N)
// list - сортируемый список
// N - число элементов
for i = 2 to N do
new list [i]
m i – 1
While (m 1) and ( list [m] > new) do
// сдвигаем все элементы, большие очередного
list [m + 1] list [m]
m m – 1
endwhile
list [m + 1] new
endfor
end
Этот алгоритм заносит новое вставляемое значение в переменную new. Затем он освобождает место для этого нового элемента, сдвигая (в цикле while) все большие элементы на одну позицию вправо. Последняя итерация переносит элемент с номером m+1 в позицию (m+2). Это означает, что позиция (m+1) освобождается для «нового элемента».
Анализ наихудшего случая - видно, что наибольшее число операций в цикле while выполняется в случае, если вновь добавляемый элемент меньше всех элементов, содержащихся в уже отсортированной части списка. В этой ситуации выполнение цикла завершается, когда значение m равно 0.
Такое неудачное расположение соответствует тому, что элементы исходного списка идут в убывающем порядке.
Как ведется обработка такого списка?
Первым вставляем второй элемент. Он сравнивается с одним элементом, второй вставленный элемент (третий по порядку) сравнивается с двумя предыдущими, а третий вставляемый элемент – с тремя предыдущими и т.д. (следовательно i – ый с i предыдущими), и этот процесс повторяется (N – 1) раз.
Общее число проходов цикла while может быть вычислено следующим образом:
fА(N) = =
Следовательно, асимптотически fА1(N) = O (N2/2).
В среднем случае необходимое количество сравнений определяется половиной длины текущей отсортированной части списка, что дает оценку
fА(N) = O(N2/4).
Пример 3.1 Сортировка методом вставки
(7 3 9 4 2 5 6 1 8) -- исходный список
На первом шаге отсортированный список состоит из одного элемента (7).
На следующем шаге в этот отсортированный список добавляется новый элемент (3). Его значение сравнивается с последним элементом в отсортированной части (3<7), следовательно, значение 7 надо сдвинуть вправо, дав возможность разместить на месте 3. После второго шага (сравнений 1, сдвиг 1) список имеет вид: (3 7 9 4 2 5 6 1 8). (Жирным начертанием выделена отсортированная часть списка).
На третьем шаге в отсортированный двухэлементный список добавляется новый элемент (9). Его значение не меньше последнего элемента, следовательно, он добавляется в конец списка (сравнений 1, сдвига нет). Список имеет вид:
7 9 4 2 5 6 1 8)
На следующем шаге добавление 4 приведет к сдвигу двух элементов (7 и 9), при этом будет выполнено 3 сравнения. Вид списка: (3 4 7 9 2 5 6 1 8).
Далее процесс повторяется. Общее число операций для этого списка будет: сравнений - 26, сдвига - 19.