
- •Вопрос 20. Метод Хоара
- •Вопрос 21. Сортировка выбором
- •Вопрос 23. Пирамидальная сортировка
- •Построение пирамиды
- •Вопрос 25. Uml.Терминология и нотация
- •Вопрос 26. Диаграммы uml
- •Вопрос 27. Диаграмма прецедентов
- •Вопрос 28. Диаграмма классов
- •Вопрос 29. Диаграмма объектов
- •Вопрос 30. Диаграмма последовательностей
- •Вопрос 31. Диаграмма взаимодействия
- •Вопрос 32. Диаграмма состояний
- •Вопрос 33. Диаграмма активности
- •Вопрос 34. Диаграмма развертывания
- •Вопрос 35. Понятие метрики. Применения метрик. Метрические шкалы.
- •Вопрос 36. Метрики сложности программ. Метрика Холстеда.
- •Вопрос 37. Метрики сложности потокауправления программ.
- •Вопрос 38. Верификация и валидация программ
- •Вопрос 39. Методы доказательства правильности программ
- •Методы доказательства правильности программ, появились в 80–е годы, делятся на два класса:1. Точные методы доказательства правильности программ.
- •Общая характеристика формальных методов доказательства
- •Вопрос 40. Методы тестирования программ
- •. Статические методы тестирования
- •. Динамические методы тестирования
- •. Функциональное тестирование
Вопрос 20. Метод Хоара
Метод быстрой сортировки придуман в 1960 году английским математиком Чарльзом Хоаром. Есть несколько причин популярности быстрой сортировки. Во-первых действительно самый быстрый алгоритм. Во-вторых: в отличие от других алгоритмов его намного проще реализовать. Он не требует никакой дополнительной памяти за исключением небольшого стека, внутренний цикл этого алгоритма очень прост и короток.
Недостатки: неустойчивость быстрой сортировки, то есть одинаковые ключи могут идти не в том порядке, в котором они были во входном файле.
Перейдем непосредственно к алгоритму. Он построен по принципу «разделяй и властвуй», который часто используется в программировании. Эторекурсивная реализация быстрой сортировки, хотя избавиться от рекурсии не представляет труда: достаточно завести стек нужного размера. Алгоритм заключается в следующем:
* Выбрать один элемент массива (разделитель или барьерный элемент). * Разбить массив на две группы: 1. элементы меньшие, чем разделитель 2. большие или равные разделителю * Рекурсивно отсортировать обе группы.
Напр: Ввести 7 элементов
41 67 34 0 69 24 78
Сортиовка: 78 69 67 41 34 24 0
Вопрос 21. Сортировка выбором
Имеется исходная неотсортированная последовательность x[0..n-1].
Отсортируем ее по возрастанию. Выбираем из нее наименьший элемент и ставим на первое место, то есть меняем местами найденный наименьший элемент и первый.
Затем в последовательности, начиная со 2-го элемента и до конца, аналогично ищем наименьший элемент и меняем его местами со 2-ым. И так далее до предпоследнего элемента. Сортировка заканчивается, когда в оставшейся неотсортированной последовательности остается 1 элемент.
Таким образом, алгоритм имеет (n-1) итераций. И на каждой i=([0..n-1])-ой итерации из элементов x[i..n-1] выбирается наименьший и меняется местами с x[i]. Когда i=n-1 сортировка прекращается и мы получаем отсортированную последовательность.
Пример. Имеется последовательность: 7, 2, 6, 5, 10, 4. n = 6.
Получим: 0 шаг - i = 0, min = 2(i=1), меняем местами x[0]=7 и x[1]=2, в итоге: 2, 7, 6, 5, 10, 4 1 шаг - i = 1, min = 4(i=5), меняем местами x[1]=7 и x[5]=4, в итоге: 2, 4, 6, 5, 10, 7 2 шаг - i = 2, min = 5(i=3), меняемместами x[2]=6 и x[3]=5, в итоге: 2, 4, 5, 6, 10, 7 3 шаг - i = 3, min = 6(i=3), меняем местами x[3]=6 и x[3]=6, в итоге: 2, 4, 5, 6, 10, 7 4 шаг - i = 4, min = 7(i=5), меняем местами x[4]=10 и x[5]=7, в итоге: 2, 4, 5, 6, 7, 10
псевдокод: сортировка выбором
// до n-2, а не n-1, т.к.последний элемент уже стоит на своем месте
for(i = 0; i<n-2; i++)
{k = I; t = x[i];
for(j = i+1; i<n-1; i++)
if(x[j]< t)
{ k = j; t = x[j];x[k] = x[i];x[i] = t;}}
Алгоритм делает n-1 итераций, на каждой из которых осуществляется еще n-i проходов(сравнений) и одна перестановка.
Следовательно, общее количество операций получаем:
n + (n-1 + 1) + (n-2 + 1) + ... + 2 = 1/2*(n2 + 2*n) - 1.
К достоинствам можно отнести отсутствие расхода памяти: все операции перестановки производятся на исходной последовательности.
Алгоритм - очень похож на алгоритм сортировки вставками. Можно даже сказать, что они в некотором отношении "симметричны": сортировка выбором выбирает нужный элемент из неотсортированной последовательности и вставляет его последним в отсортированную, вставками - выбирает первый элемент из неотсортированных, но вставляет его в нужное место сортированной последовательности.
Вопрос 22. Сортировка вставкой Проходимся по всем элементам и вставляем каждый текущий элемент на свое место в уже отсортированную последовательность предыдущих просмотренных элементов. В самом начале считаем первый элемент уже отсортированной последовательностью и далее проходимся по всем остальным элементам.
В результате получим: псевдокод: сортировка вставкой
for(i = 1; i<n; i++)/* элементыx[0..i-1] - уже отсортированы */
insertx[i]inx[0..i-1]/* ставим x[i] в правильную позицию */
Последовательность сортировки массива из 4-х элементов иллюстрируется ниже. Символ "|" - показывает текущее значение переменной i; элементы слева от этого символа уже отсортированы, справа - нет.
3 | 1 4 2 * 1 3 | 4 2 * 1 3 4 | 2 * 1 2 3 4 |
Вставка элемента в нужную позицию производится циклом, в котором элементы перебираются справа налево, а в переменной j хранится индекс очередного вставляемого элемента.
В цикле текущий элемент переставляется местами с предыдущим, если этот предыдущий элемент существует (т. e. j>0) и текущий элемент еще не установлен в нужное положение (он и предыдущий элементы находятся в неправильном порядке). Итак, получившаяся программа сортировки примет вид: псевдокод: сортировка вставкой, версия #1
For(i = 1; i<n; i++)
for(j = i; (j >0) &&(x[j-1]> x[j]); j--)
swap(j-1, j);
В тех случаях, когда нужно написать собственную сортировку, можно начать именно с этой функции, потому что она очень проста — всего три очевидные строки.
Программу можно ускорить, раскрыв функцию явно, хотя многие оптимизирующие компиляторы способны делать это за нас. Заменим вызов функции нижеследующим кодом, в котором переменная t используется для обмена x[j] и x[j-l]:
t = x[j]; x[j] = x[j-1]; x[j-1] = t;
После этого улучшения появляется возможность сделать следующий шаг. Поскольку переменной t несколько раз присваивается одно и то же значение (исходно находящееся в x[i]), можно вынести присваивания, относящиеся к этой переменной, за рамки внутреннего цикла, а также изменить вид сравнения, что даст третью версию сортировки вставкой:Псевдокод: сортировка вставкой, версия #3
for(i = 1; I<n, i++){
t = x[i];
for(j = i; (j >0)&&(x[j-1]> t); j--) {
x[j] = x[j-1]
x[j] = t;}}
Эта программа сдвигает элементы вправо до тех пор, пока они превосходят значение t, а потом ставит t в правильную позицию. Эта функция из пяти строк чуть сложнее своих предшественников, но работает примерно на 15% быстрее, чем вторая версия той же сортировки.