Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Технология программирования 7,8 вопросы.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
865.28 Кб
Скачать

8. Эффективные алгоритмы сортировки (быстрая, шелловская, пирамидальная, поразрядная). Сортировка подсчетом.

Быстрая сортировка

1. Общее быстродействие O(n*log(n)). Наиболее быстрая сортировка для неупорядоченных массивов с 50 и более элементами.

2. Требует дополнительной памяти.

3. Неустойчивая.

5. Поведение неестественное.

Метод основан на подходе "Разделяй и властвуй".

Быструю сортировку нетрудно реализовать, она хорошо работает на различных видах входных данных и во многих случаях требует меньше затрат ресурсов по сравнению с другими методами сортировки. На выполнение сортировки N элементов в среднем затрачивается время, пропорциональное N log N и для него характерны исключительно короткие внутренние циклы.

Его недостатком является то, что он неустойчив, для его выполнения в наихудшем случае требуется N2 операций.

Наиболее быстрой является сортировка для неупорядоченных массивов с 50 и более элементами.

Быстрая сортировка использует стратегию «разделяй и властвуй». Шаги алгоритма таковы:

  1. Выбираем в массиве некоторый элемент, который будем называть опорным элементом. С точки зрения корректности алгоритма выбор опорного элемента безразличен. С точки зрения повышения эффективности алгоритма выбираться должна медиана, но без дополнительных сведений о сортируемых данных её обычно невозможно получить. Известные стратегии: выбирать постоянно один и тот же элемент, например, средний или последний по положению; выбирать элемент со случайно выбранным индексом.

  2. Операция разделения массива: реорганизуем массив таким образом, чтобы все элементы со значением меньшим или равным опорному элементу, оказались слева от него, а все элементы, превышающие по значению опорный — справа от него. Обычный алгоритм операции:

    1. Два индекса — i и j, приравниваются к минимальному и максимальному индексу разделяемого массива, соответственно.

    2. Вычисляется индекс опорного элемента m.

    3. Индекс i последовательно увеличивается до тех пор, пока i-й элемент не окажется больше либо равен опорному.

    4. Индекс j последовательно уменьшается до тех пор, пока j-й элемент не окажется меньше либо равен опорному.

    5. Если i = j — найдена середина массива — операция разделения закончена, оба индекса указывают на опорный элемент.

    6. Если i < j — найденную пару элементов нужно обменять местами и продолжить операцию разделения с тех значений i и j, которые были достигнуты. Следует учесть, что если какая-либо граница (i или j) дошла до опорного элемента, то при обмене значение m изменяется на i-й или j-й элемент соответственно, изменяется именно индекс опорного элемента и алгоритм продолжает свое выполнение.

  3. Рекурсивно упорядочиваем подмассивы, лежащие слева и справа от опорного элемента.

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

Рассмотрим пример.

9i 6 1 3 2j

Находим медиану (m =1).

Индексы i и j присваиваем первому и последнему элементам соответственно.

Сравниваем: 9>=1? да. 2<=1? нет => j сдвигается влево, i остается на месте.

9i 6 1 3j 2

Сравниваем: 9>=1? да. 3<=1? нет => j сдвигается влево, i остается на месте

9i 6 1j 3 2

Сравниваем: 9>=1? да. 1<=1? да => меняем местами i-ый и j-ый элементы.

1i 6 9j 3 2

Сравниваем: 1>=1? да. 9<=1? нет => j сдвигается влево, i остается на месте

1i 6j 9 3 2

Сравниваем: 1>=1? да. 6<=1? нет => j сдвигается влево, i остается на месте

1ij 6 9 3 2

i = j — найдена середина массива — операция разделения закончена, оба индекса указывают на опорный элемент.

Рекурсивно упорядочиваем подмассивы, лежащие слева и справа от опорного элемента:

1 | 6i 9 3 2j

Сравниваем: 6>=9? нет. 2<=9? да => i сдвигается вправо, j остается на месте.

1 | 6 9i 3 2j

Сравниваем: 9>=9? да. 2<=9? да => меняем местами i-ый и j-ый элементы.

1 | 6 2i 3 9j

Сравниваем: 2>=9? нет. 9<=9? да => i сдвигается вправо, j остается на месте

1 | 6 2 3i 9j

Сравниваем: 3>=9? нет. 9<=9? да => i сдвигается вправо, j остается на месте

1 | 6 2 3 9ij

i = j — найдена середина массива — операция разделения закончена, оба индекса указывают на опорный элемент.

Рекурсивно упорядочиваем подмассивы, лежащие слева и справа от опорного элемента:

1 | 6i 2 3j | 9

Сравниваем: 6>=2? да. 3<=2? нет => j сдвигается влево, i остается на месте

1 | 6i 2j 3 | 9

Сравниваем: 6>=2? да. 2<=2? да => меняем местами i-ый и j-ый элементы

1 | 2i 6j 3 | 9

Сравниваем: 2>=2? да. 6<=2? нет => => j сдвигается влево, i остается на месте

1 | 2ij 6 3 | 9

i = j — найдена середина массива — операция разделения закончена, оба индекса указывают на опорный элемент.

Рекурсивно упорядочиваем подмассивы, лежащие слева и справа от опорного элемента:

1 2 | 6i 3j | 9

Аналогично сравниваем 6 и 3. Получаем: 1 2 3 6 9

Сортировка методом Шелла