Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
redakt.docx
Скачиваний:
0
Добавлен:
23.01.2020
Размер:
395.72 Кб
Скачать

Вопрос 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% быстрее, чем вторая версия той же сортировки.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]