- •Алгоритмы и структуры данных
- •Лекция 1 Тема 1.1. Критерии оценки алгоритмов
- •1.1.1. Асимптотические характеристики
- •Временная оценка (оценка порядка)
- •Общий случай определения временной сложности
- •Тема 1.2. Классификация алгоритмов по степени сложности
- •Виды функций оценки сложности алгоритмов
- •Экспериментальный метод оценки трудоемкости (сложности) алгоритма
- •Оценка пространственной (емкостной) сложности
- •Линейные структуры данных
- •Иерархические структуры данных
- •Сетевые структуры данных
- •Табличные структуры данных
- •Представление данных в памяти эвм
- •Базовые алгоритмы обработки данных
- •Тема 2.2. Алгоритмы обработки данных линейной структуры
- •3. Алгоритмы сортировки
- •3.1. Основные определения и классы алгоритмов
- •Наиболее распространенные простые алгоритмы внутренней сортировки (массивов)
- •Сортировка вставками
- •Сортировка выбором
- •3.2.3. Сортировка обменом (Пузырьковая сортировка)
- •3.2.4.Сортировка Шейкером
- •Эффективные методы внутренней сортировки
- •Сортировка Шелла
- •3.3.2. Быстрая сортировка
- •3.4.3. Сортировка Боуза - Нельсона
Общий случай определения временной сложности
Оценку сложности алгоритмов выполняют с использованием аппарата математического асимптотического анализа и выведения асимптотической оценки сложности.
Выражение (1.1) представляет собой точную оценку сложности алгоритмов. В теории алгоритмов они являются семейством функций, дающих множество значений, в том числе верхнее и нижнее. Основным свойством Θ(n) является то, что при увеличении размерности входных данных n время выполнения алгоритма возрастает с той же скоростью, что и функция f(n). Ее еще называют асимптотической.
Асимптотическая оценка сложности обозначается греческой буквой Θ (тета).
f(n) = Θ(g(n)), если существуют c1, c2>0 и n0 такие, что c1*g(n)<=f(n)<=c2*g(n) , при n>n0.
Функция g(n) является асимптотически точной оценкой сложности алгоритма - функции f(n). Приведенное неравенство называется асимптотическим, а само обозначение Θ символизирует множество функций, которые растут «так же быстро», как и функция g(n) – т.е. с точностью до некоторой константы c1 или c2.
Как следует из приведенного неравенства, Θ представляет собой одновременно и верхнюю, и нижнюю оценки сложности. Не всегда имеется возможность получить выражение в общем виде, поэтому верхнюю и нижнюю оценки могут определять отдельно.
Верхняя оценка сложности обозначается греческой буквой Ο (омикрон), и является множеством функций, которые растут не быстрее, чем g(n).
f(n)= Ο(g(n)), если существует c>0 и n0 такие, что 0<=f(n)<=cg(n), при n>n0.
Нижняя оценка сложности обозначается греческой буквой Ω (омега), и является множеством функций, которые растут не медленнее, чем g(n).
f(n)= Ω(g(n)), если существует c>0 и n0 такие, что 0<=cg(n)<=f(n), при n>n0.
Вообще, асимптотическая оценка существует только в том случае, если совпадают нижняя и верхняя оценки сложности алгоритма. В практике анализа алгоритмов чаще всего используют верхнюю оценку. Это вполне логично, поскольку наиболее важна оценка времени, за которое алгоритм гарантировано закончит работу, а не время, в пределах которого он точно не завершится.
Таким образом, верхняя оценка сложности является оценкой порядка и пропорциональна максимальному элементу в формуле Θ(n) (см. (1.1)). Она легче вычисляется и дает предельное значение. Именно она получила наибольшее распространение.
Обычно определение сложности алгоритма сводится к анализу
Циклов;
Вызовов методов и
Вызовов рекурсий.
Так, в примере 1 (нахождение суммы элементов квадратной матрицы) она определяется величиной O(n2), а в примере 2 (нахождение максимума в одномерном массиве) для всех случаев – O(n). Вообще для циклов вида:
for (i=1; i<= n;i++)
for (j=1; j<= n;j++)
for (k=1; k<= n;k++)
{Тело цикла}
сложность равна O(n3), т.е. пропорциональна числу повторений самого внутреннего цикла.
Тема 1.2. Классификация алгоритмов по степени сложности
Виды функций оценки сложности алгоритмов
В общем случае, О-функции выражают относительное быстродействие алгоритма в зависимости от некоторой переменной или переменных. При этом используются три правила оценки сложности.
O(k*f) = O(f),
O(f*g) = O(f)*O(g),
O(f+g) = Max (O(f), O(g)).
Здесь k обозначает константу, а f и g - функции.
Первое правило означает, что постоянные множители не имеют значения для определения порядка сложности, например, O(2*n) = O(n). В соответствии со вторым порядок сложности произведения двух функций равен произведению их сложностей. Например, O((10*n)* n) = O(n)* O(n) = O(n2). На основании третьего правила порядок сложности суммы двух функций равен максимальному (доминирующему) значению из их сложностей. Например, O(n4 + n2) = O(n4).
На практике применяются следующие виды О-функций:
О(1) – константная сложность, для алгоритмов, сложность которых не зависит от размера данных.
О(n) – линейная сложность, для одномерных массивов и циклов, которые выполняются n раз,
О(n2), О(n3), … – полиномиальная сложность, для многомерных массивов и вложенных циклов, каждый из которых выполняется n раз,
О(log(n)) – логарифмическая сложность, для программ, в которых большая задача делится на мелкие, которые решаются по-отдельности,
О(2n) – экспоненциальная сложность, для очень сложных алгоритмов, использующих полный перебор или так называемый «метод грубой силы».
Функции перечислены в порядке возрастания сложности. Чем выше в этом списке находится функция, тем быстрее будет выполняться алгоритм с такой оценкой.
