- •3. Анализ алгоритмов сортировки и поиска
- •1. Алгоритмы поиска
- •Int b_find(int* a, int n, int key) // key – искомое значение
- •2. Задачи сортировки. Сортировка методом парных перестановок
- •Void sort_pair(int* a, int n)
- •3. Метод пузырька
- •Void sort_bubble(int* a, int n)
- •4. Сортировка методом вставки
- •5. Метод слияния
- •Void merge(int* a, int p, int q, int r)
- •Void sort_merge(int* a, int n, int p, int r)
- •6. Метод вычерпывания
- •7. Результаты тестирования
2010.09.01
В.П. Пинчук
Анализ и построение алгоритмов и структуры данных для спец. КСС. -
Запорожье: ЗНТУ, 2010.
3. Анализ алгоритмов сортировки и поиска
1. Алгоритмы поиска
2. Сортировка методом парных перестановок
3. Метод пузырька
4. Метод вставки
5. Метод слияния
6. Метод вычерпывания
7. Результаты тестирования
1. Алгоритмы поиска
Задача
Дано: одномерный массив А размером n и искомое значение key.
Требуется: определить, содержит ли массив А значение key и, если да, то получить номер соответствующего элемента массива А.
Поиск в неупорядоченном массиве (последовательный поиск)
Достоинством алгоритма последовательного поиска является то, что он работает на неупорядоченных последовательностях. Недостаток - невысокая эффективность, алгоритм имеет линейный порядок, асимптотический класс O(n).
Искомое значение key последовательно сравнивается с элементами массива А. Наихудший случай будем иметь, когда искомое значение отсутствует в массиве, наилучший – когда искомое значение совпадает с первым элементом массива. Отсюда:
t Constn ,
или t = f(n) = O(n) .
Т.о. рассматриваемый алгоритм является линейным по времени.
Поиск в упорядоченном массиве. Алгоритм бинарного поиска
Алгоритм бинарного поиска применим в случае, когда последовательность предварительно упорядочена. Ниже приведен пример функции, выполняющей бинарный поиск для массива, упорядоченного по возрастанию.
Int b_find(int* a, int n, int key) // key – искомое значение
{ int p = 0, q = n-1, k; // [p,q] – отрезок массива
while (q >= p) { k = p + (q-p)/2; // k – номер среднего эл-та
if (A[k] == key) return k;
if (A[k] < key) p = k + 1;
else q = k - 1;
}
return -1; // значение key не найдено
}
На каждом шаге этого алгоритма текущий отрезок массива делится на две части, размеры которых отличаются не более чем на единицу. Размер текущего отрезка массива на каждом шаге уменьшается в 2 раза (даже немного больше, чем в 2 раза, т.к. средний элемент на каждом шаге выбывает). Процесс завершается, когда размер очередного отрезка массива оказывается равным единице. Отсюда время будет равно:
t Constlog2(n) .
Отсюда: t = f(n) = O(log2(n)) .
Результаты прямых экспериментов
Абсолютное время решения задачи поиска для n = 100 000 000 (худший случай, процессор E8400):
последовательный поиск: 80650 мкс
бинарный поиск: 3 мкс
2. Задачи сортировки. Сортировка методом парных перестановок
Алгоритмы решения задачи сортировки лежат в основе многих приложений (особенно следует отметить базы данных и экспертные системы). Задача поиска элемента с заданным значением решается намного быстрее, если массив предварительно упорядочен.
Назовем некоторые основные методы решения задачи сортировки:
- метод пузырька (существуют разные модификации);
- метод вставки;
- метод слияния.
Для представления алгоритмов будем использовать язык С++. Напомним, что, согласно правилам этого языка, элементы массива, имеющего n элементов имеют номера от 0 и до n-1.
Метод парных перестановок
Основой этого алгоритма является операция парного упорядочивания (упорядочивание пары соседних элементов массива). Пары упорядочиваются последовательно, начиная с первой пары (элементы с номерами 0, n-1) и до последней (элементы с номерами n-2, n-1). Для того, чтобы гарантировать полное упорядочивание любого массива, необходимо выполнить n-1 проходов парного упорядочивания. Таким образом, алгоритм содержит двойной цикл. Ниже представлен фрагмент программы, выполняющий сортировку массива A размером n элементов по убыванию.
Рассматриваем направление сортировки - по возрастанию.