Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

информатика.Методы сортировок

.pdf
Скачиваний:
10
Добавлен:
04.06.2015
Размер:
2.25 Mб
Скачать

} //Конецфункцииратпоп

void qиiсksоrt (DataType theArray {), int jirst, int last)

!/ ----------------------------------------------------------------------------­

1/ Упорядочивает элементы массива в возрастающем порядке. // Предусловие: отрезок theArray [first.. last} - массив.

// Постусловие: массивtheArray[first..last} упорядочен. // Вызываемаяфункция: partition.

!/ ----------------------------------------------------------------------------­

{

int pivotlndex; if (first < last)

(

// Создаемразбиение: 8L опорный элемент. S2

partition(theArray, Lfirst, last, pivotlndex):

// Упорядочиваеммножества8/ и 82

qиiсksогt(thеАrrау, jirst, pivotlndex-l): qиiсksоrt(thеАrгау, pivotlndex+l, last):

} // Конец оператора ~r }// Конец функцииqиiсksоrt

Дальнейший анализ покажет, что желательно избегать такого выбора опорного элемента, при котором множество Sj или S2 оказываются пустыми. Лучше всего выбирать опорный элемент поближе к медиане массива.

Алгоритмы guickSort и mergeSort «близки по духу», хотя в алгоритме guickSort основная работа выполняется до рекурсивных

вызовов, а в алгоритмеmergeSort - после.

Схему псевдокода алгоритма guickSort можно записатьтак.

qиiсksоrt (inout theArray: ItemArray, injirst .-integer, т last: integer)

if (first < last)

{

Подготовить массив theArray крекурсивным вызовам

qиiсksогt (отрезок ..Sl массива

theArray)

qиiсksогt (отрезок 82 массива

theArray)

}// Конец оператора ij'

Вто же время общая схема алгоритма mergeSol-еt выглядит следующимобразом.

• mergesort (inout theA1Aray: ItemArray, [п jirst: integer, in Zast: integer)

If (first < Zast,·

{

mergesort (левая часть массива (пеАпау) тепгезоп (правая часть массива (пеАпау)

Собратьмассив, полученныйпослерекурсивныхвызовов } // Конец оператора ~f·

Перед вызовом функции quicksort выполняетсяразбиение массива на

части 8/ и S2. Затем алгоритм

упорядочивает отрезки 8/ и 82 независимо друг

от друга, поскольку любой

элемент отрезка 8/ находится левее любого

40

элемента отрезка S2. В функции mergeSort, наоборот, перед рекурсивными вызовами никакая работа не выполняется. Алгоритм упорядочивает каждую из частей массива, постоянно учитывая отношения между элементами обеих частей. По этой причине алгоритм должен объединять две половины массива

после выполнения рекурсивных вызовов.

Анализ. Основная работа в алгоритме quicksort выполняется на этапе разбиения массива. Анализируя каждый элемент, принадлежащий неопределенной части, необходимо сравнивать элемент theArray {firstunknown] с опорным и помещать его либо в отрезок 8/, либо в отрезок 82. Один из отрезков 8/, или S2 может быть пустым; например, если опорным элементом является наименьший элемент отрезка, множество SI останется пустым. Это происходит в наихудшем случае, поскольку размер отрезка 82 при каждом вызове функции quicksort уменьшается только на единицу. Таким образом, в этой ситуации будет выполнено максимальноеколичество рекурсивныхвызовов функции quicksort.

Исходный

массив

Опорный

 

Неопределеннаячасть

 

 

 

 

 

 

 

 

 

 

 

 

элемент

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

5

I\I~I

 

 

 

 

 

 

 

 

Опорный

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

элемент

82

 

Неопределенная часть

Множество

81 пусто

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

5

6

 

.t;:i\~

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Опорный

 

 

 

 

 

 

 

 

 

 

 

элемент

 

 

 

Неопределенная часть

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

5

6

7

····:·····::~ill::I

Множество

51 пусто

 

 

 

 

 

 

~~~(~{

...... .:,:. .i,:..•.:,.:!,:.'....;i,......:;I.::::•.:..•I:.•:::!:;:.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Опорный

 

 

 

 

 

 

 

 

 

 

 

элемент

 

 

 

 

 

 

 

Множество

81 пусто

 

 

 

5

6

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Опорный

 

 

 

 

 

 

 

 

 

 

Первое

элемент

 

 

 

 

 

 

 

Множество

51 пусто

 

 

 

 

 

 

 

 

 

 

 

 

 

5

6

 

 

 

 

 

 

 

разбиение

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

4 сравнения, Оперестановок

 

 

 

 

 

 

 

 

 

 

 

Рисунок 19.. Разбиениемассивав алгоритмеqиiсksоrtв наихудшемварианте

 

При следующем рекурсивном вызове функции quicksort

функция

partition просмотрит n-l

элемент. Чтобы

распределить их по

отрезкам,

понадобится n-2 сравнений. Поскольку размер отрезка, рассматриваемого функцией quicksort, на каждом уровне рекурсии уменьшается только на

41

единицу, возникнет n-1 уровней рекурсии. Следовательно, функция

quicksort выполняет

1 + 2 + ...+ (n-l) == n * (n-l)/2

сравнений. Напомним, однако, что при переносе элемента в множество 82 выполнять перестановку элементов не обязательно. Для этого достаточно лишь изменить индекс firstUnknown.

Аналогично, если множество 82 при каждом рекурсивном вызове остается пустым, потребуется п * (n -1)/2 сравнений. Кроме того, в этом случае для переноса каждого элемента из неизвестной части в множество 81 придется выполнять перестановку элементов. Таким образом, понадобится n * (n -1)/2 перестановок. (Напомним, что каждая перестановка выполняется с

помощью трех операций присваивания.) Итак, в худшем случае сложность

алгоритма quicksort равна О( n 2).

Для контраста на рис. 20 продемонстрирован пример, когда множества 8] и 82 состоят из одинакового количества элементов. В среднем случае, когда множества Sl и S2 состоят из одинакового - или приблизительно одинакового - количества элементов, записанных в произвольном порядке, рекурсивных вызовов функции quick801At потребуется меньше. Как и при анализе алгоритма merge8ort, легко показать, что глубина рекурсии в алгоритме quick80rt равна log2n или log2n+ 1. При каждом вызове функции quick80rt выполняетсят сравнений и не больше, чем m перестановок, где т - количество элементов в

подмассиве, подлежащем сортировке.

42

Исходный

массив

Опорный

 

 

Неопределенная часть

 

 

 

 

 

 

 

 

 

 

элемент

 

 

 

 

 

 

 

 

 

 

 

 

 

Опорный

 

 

 

 

 

 

 

 

 

 

 

 

 

элемент

5,

 

 

 

Неопределенная часть

 

 

 

 

iI

 

 

 

 

 

5

 

3

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Опорный

 

 

 

 

 

 

 

 

 

 

 

 

 

элемент

5,

 

 

 

52 Неопределенная часть

 

 

 

 

 

 

 

 

"

, , " .

 

 

 

 

5

 

3

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Опорный

 

 

 

 

 

 

 

 

 

 

 

 

 

элемент

8,

 

 

82

 

Неопределенная часть

 

 

 

 

5

 

3

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Опорный

 

 

 

 

 

 

 

 

 

 

 

 

 

элемент

 

 

5,

 

 

52

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

5

 

 

4

 

7

 

 

Множества 81

и 52 определены

 

3

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Первое

разбиение

 

 

>S

 

 

 

 

 

:r:

 

 

 

 

:I:

Ф

 

 

 

 

Q..~

 

 

 

 

О

Ф

 

 

 

 

с

с:

 

 

51

0(1)

 

52

 

 

 

3

5

 

7

 

Вставляем опорный элемент

 

 

 

 

 

 

между множествами 51 и 52

 

 

 

 

 

 

РИСУНОК 20. Разбиение массива в алгоритме ашскзоп в среднем варианте

Формальный анализ алгоритма quicksort для среднего варианта показывает, что его сложностьявляется величинойO(n*log n). Таким образом, с большими массивами алгоритм quicksort работает значительно быстрее, чем алгоритм insertionSort, хотя в наихудшемварианте они оба имеют приблизительноодинаковоебыстродействие.

Алгоритм quicksort часто используется для сортировки больших массивов. Причина его популярности заключается в исключительном быстродействии, несмотря на обескураживающие оценки наихудшего варианта. Дело в том, что этот вариант встречается крайне редко, и на практике алгоритм quicksort отлично работает с относительно большими

массивами.

Значительное различие между оценками сложности в среднем и наихудшем вариантах выделяет алгоритм быстрой сортировки среди остальных алгоритмов, рассмотренных в данной главе. Если порядок записи элементов в исходном массиве является "случайным", алгоритм quickSort работает, по крайней мере, не хуже любого другого алгоритма,

43

использующего сравнения элементов. Если исходный массив совершенно не упорядочен, алгоритм quickSort работает лучше всех.

Алгоритм mergeSort имеет приблизительно такую же эффективность. В некоторых случаях быстрее работает алгоритм quickSort, в других ­ алгоритм mergeSort. Несмотря на то, что оценка сложности алгоритма mergeSort в наихудшем варианте имеет тот же порядок, что и оценка сложности алгоритмаquickSort в среднем варианте, в большинствеслучаев алгоритм quickSort работает несколько быстрее. Однако в наихудшем варианте быстродействиеалгоритма quicksort намного ниже.

Сравнениеалгоритмовсортировки

На рис.21 показаны приближенныеоценки сложностиалгоритмов

сортировки, в наихудшем и среднем вариантах.

Сортировка

Наихудший вариант

Средний вариант

 

 

 

Методом выбора

n 2

n 2

Методом пузырька

n 2

n 2

Методом вставок

n 2

n 2

Методом слиянием

n*log п

n*log п

Быстрая

n'l

n*log п

РИСУНОК2J. Приближенные оценки сложности алгоритмов сортировки

Лабораторная работа «Методы сортировок»

Цель рвботы

Изучение алгоритмов сортировок и оценка их эффективности.

Задания на лабораторную работу «Методы сортировок»

Общее задание

в данной лабораторной работе требуется разработать программу, выполняющую следующие действия:

1. Ввод размера массива (или двух - в зависимости от задания)

2.

3.

4.

5.

Ввод исходного массива (массивов) Вывод введенных массивов

Обработка массива (массивов) в соответствии с вариантом Вывод получившихся массивов

44

Замечания:

1) Количество элементов в исходных массивов до 20 ШТУК. 2) Элементами массивов являются целые числа.

3) Множества в программах не использовать.

4) После каждого изменения массивов новое состояние необходимо

вывести на экран.

5) "Скопировать элементы" элементы из исходного массива добавляются в результирующий массив.

6) "Перенести элементы" элементы из исходного массива добавляются в результирующий массив, после чего удаляются из

исходного.

Ввривнты

1. Ввести массив А. В массив В скопировать все элементы массива А имеющие четный индекс и четное значение. Массив В отсортировать по убыванию, используя метод выбора.

2. Ввести массив А. В массив В перенести все элементы массива А имеющие четный индекс и нечетное значение. Массив В отсортировать по

возрастанию, используя метод пузырька.

3. Ввести массив А. В массив В скопировать все элементы массива А, имеющие четный индекс, слева от которых расположены элементы снечетным значением. Массив В отсортировать по возрастанию, используя метод вставок.

4. Ввести массив А. В массив В перенести все элементы массива А, имеющие четный индекс, справа от которых расположены элементы с нечетным значением. Массив В отсортировать по убыванию, используя метод

слияния.

5. Ввести массив А. В массив В перенести все элементы массива А, имеющие нечетный индекс, справа от которых расположены элементы с нечетным значением, а слева - с четным. Массив В отсортировать по убыванию, используя быструю сортировку.

6. Ввести массив А. В массив В перенести все элементы массива А, стоящие левее минимального элемента, и имеющие нечетный индекс. Массив В отсортировать по убыванию, используя быструю сортировку.

45

7. Ввести массив А. В массив В перенести все элементы массива А, стоящие правее максимального элемента, и имеющие нечетный индекс. Массив

Вотсортировать по возрастанию, используя метод слияния.

8.Ввести массив А. В массив В перенести все элементы массива А, стоящие между минимальным и максимальным элементами. Массив В

отсортировать по возрастанию, используя метод вставок.

9. Ввести массив А. В массив В перенести все элементы массива А, имеющие значение больше чем (min+max)/2, где min - значение минимального элемента массива, а тах - значение максимального элемента массива. Массив В отсортировать по убыванию, используя метод пузырька.

10. Ввести массив А. В массив В перенести все элементы массива А, имеющие значение меньше чем (min+max)/3, где min - значение минимального элемента массива, а тах - значение максимального элемента массива. Массив В отсортировать по убыванию, используя сортировку методом выбора.

11. Ввести массивы А и В. В массив С скопировать те элементы, которые есть и в массиве А и в массиве В. Из массива В удалить все четные элементы. Массивы А, В и С отсортировать по возрастанию, используя метод выбора.

12. Ввести массивы А и В. В массив С скопировать те элементы, которые есть в массиве А, но которых нет в массиве В. Из массива А удалить все нечетные элементы. Массивы А, В и С отсортировать по убыванию, используя быструю сортировку.

13. Ввести массивы А и В. В массив С скопировать те элементы массива А, которых нет в массиве В, и те элементы массива В, которых нет в массиве А. Из массива В удалить все четные элементы. Массивы А, В и С отсортировать

по возрастанию, используя сортировку методом слияния.

14. Ввести массивы А и В. В массив С скопировать те элементы массива А, которых нет в массиве В, и те элементы массива В, которые встречаются в массиве А по крайней мере 2 раза. Из массива А удалить все элементы стоящие левее минимального элемента. Массивы А, В и С отсортировать по убыванию,

используя сортировку методом вставок.

15. Ввести массивы А и В. В массив С скопировать те элементы массива А, которые встречаются в массиве В по крайней мере 2 раза, и те элементы массива В, которые встречаются в массиве А ровно 1 раз. Из массива А удалить все элементы стоящие левее максимального элемента. Массивы А, В и С отсортировать по убыванию, используя сортировку методом пузырька.

46

16. Ввести массивы А и В. В массив С перенести те элементы массива А, которые меньше минимального элемента массива В, и те элементы массива В, которые больше максимального элемента массива А. Массивы А, В и С отсортировать по возрастанию,используя сортировку методом выбора.

17. Ввести массивы А и В. В массив С перенести те элементы массива А, которые больше минимального элемента массива В, и те элементы массива В, которые больше максимального элемента массива А. Массивы А, В и С

отсортировать по возрастанию, используя метод пузырька.

18. Ввести массивы А и В. В массив С перенести те элементы массива А, которые больше максимального элемента массива В, и те элементы массива В, которые меньше максимального элемента массива А. Массивы А, В и С отсортировать по убыванию, используя метод пузырька.

19. Ввести массивы А и В. В массив С перенести четные элементы массива А, и нечетные элементы массива В. Массивы А, В и С отсортировать по убыванию, ИСПОЛЬЗУЯ сортировку методом вставок.

20. Ввести массивы А и В. В массив С перенести те четные элементы массива А, левее которых стоят элементы с нечетным значением. Также в массив С перенести элемент массива В, который по значению ближе всех к (min+max)/2, где min - значение минимального элемента массива В, шах ­ значение максимального элемента массива В. Массивы А, В и С отсортировать

по возрастанию, используя сортировку методом слияния.

21. Ввести массивы А, В и С. в массив D скопировать те элементы массивов А, В и с, которые встречаются во всех трех массивах. Массивы А, В,

Си D отсортировать по возрастанию, используя быструю сортировку.

22.Ввести массивы А, В и С. в массив D скопировать те элементы массивов А и В, которых нет в массиве С. Массивы А, В, С и D отсортировать по убыванию, используя сортировку методом слияния.

23.Ввести массивы А, В и С. В массив О перенести из массива А те элементы, левее которых расположены элементы, имеющие значение больше

(minB+maxC)/3, где minB - значение минимального элемента массива В, а тахС

-значение максимального элемента массива С. Массивы А, В, С и D

отсортировать по возрастанию, используя сортировку методом вставок.

24. Ввести массивы А, В и С. в массив О перенести из массива А те

элементы, правее которых расположены элементы, имеющие значение меньше

чем (minB+maxC)/2, где minB - значение минимального элемента массива В, а

47

тахС - значение максимального элемента массива с. Массивы А, В, С и D отсортировать по возрастанию, используя сортировку методом пузырька.

25. Ввести массивы А, В и с. в массив D перенести из массива А те

элементы, правее которых расположены элементы, имеющие значение

меньше чем (minB+maxC)/2, где minB - значение минимального элемента массива В, а тахе - значение максимального элемента массива С. Из массива С удалить те элементы, которые имеют значение больше максимального элемента массива В. Массивы А, В, С и D отсортировать по убыванию, используя сортировку методом выбора.

Библиографический список

1.

Седжвик, Р.

Фундаментальные алгоритмы на С++.

Анализ/Структуры

 

данных/Сортировка/Поиск: пер. сангл. - К.: Издательство «Диасофт»,2001. - 688

 

с.

 

 

2.

Шилдт, Г. Полный справочник по С++, 4-е ИЗД.: пер. сангл. -

М.: Издательский

 

дом «Вильямс», 2002. - 704 с.

 

3.

Каррано, Ф. М Абстракция данных и решение задач на С++. Стены и зеракала, 3-е

 

изд.,пер. сангл. -

М.: Издательский дом «Вильямс».,2003. - 848 с.: ил.

Учебное издание Методы сортировки и их реализации

Составители: БЕЛЯЕВА Ирина Владимировна, БЕЛЯЕВ Константин Сергеевич

Редактор А.Камышанов Подписано в печать 08 . 11.2006. Формат 60х84 1/16. Бумага офсетная.

Печать трафаретная. Усл. печ. л.2,79 .Тираж 100 экз.

Заказ N2/S5.г.

Ульяновский государственный технический университет, 432027, г.Ульяновск, ул. Северный Венец, 32.

Типография УлГТУ, 432027, г.Ульяновск, УЛ. Сев. Венец, 32.