Опубликован: 05.01.2015 | Доступ: свободный | Студентов: 2178 / 0 | Длительность: 63:16:00
Лекция 7:

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

Разбиение по медиане из трех

Другим усовершенствованием быстрой сортировки является использование центрального элемента, который с большей вероятностью делит файл близко к середине. Есть несколько возможностей сделать это. Достаточно надежный способ избежать худшего случая состоит в использовании случайного элемента массива в качестве центрального. Тогда вероятность наихудшего выбора пренебрежимо мала. Этот метод является простым примером вероятностного алгоритма (probabilistic algorithm) - алгоритма, который использует случайный выбор для достижения хорошей производительности с высокой вероятностью, независимо от упорядоченности входных данных. Далее в этой книге мы увидим многочисленные примеры использования случайного выбора при разработке алгоритмов, особенно если возможна регулярность входных данных. На практике использование генератора случайных чисел для быстрой сортировки может оказаться излишним: достаточно эффективен простой произвольный выбор.

Другой распространенный способ определения лучшего центрального элемента заключается в выборке трех элементов из файла и использовании в качестве центрального элемента их медианы. Если выбрать за эти три элемента левый, правый и средний элементы массива, то заодно можно включить в схему и сигнальные элементы: сортируем три выбранных элемента (используя метод трех обменов, описанный в "Элементарные методы сортировки" ), потом обмениваем средний из них с элементом a[r-1], и затем выполняем алгоритм разбиения для a[l+1], ..., a[r-2]. Это усовершенствование называется методом медианы из трех (median-of-three).

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

Сочетание метода медианы из трех с отсечением небольших подфайлов может улучшить время выполнения быстрой сортировки по сравнению с элементарной рекурсивной реализацией на 20-25%. Программа 7.4 представляет собой реализацию, вобравшую в себя все эти усовершенствования.

Можно было бы продолжить усовершенствование программы, удалив рекурсию, заменив вызовы подпрограмм непосредственной вставкой их кода, используя сигнальные значения и т.п. Однако в современных машинах такие вызовы процедур вполне эффективны, и они находятся вне внутреннего цикла. Более важно то, что применение отсечения небольших подфайлов компенсирует возможные дополнительные затраты (вне внутреннего цикла). Основной причиной использования нерекурсивной реализации с явным стеком является гарантированное ограничение размера стека (см. рис. 7.10).

 Размер стека для усовершенствованного варианта быстрой сортировки

Рис. 7.10. Размер стека для усовершенствованного варианта быстрой сортировки

Сортировка вначале меньшего подфайла гарантирует, что даже в худшем случае размер стека будет логарифмически зависеть от размера файла. Здесь приведены графики размеров стека для тех же файлов, что и на рис. 7.5, но при сортировке вначале меньшего подфайла (слева) и с добавлением модификации медианы из трех (справа). Эти диаграммы никак не связаны с временем выполнения, которое зависит скорее от объема файлов в стеке, чем от их количества. Например, для третьего (частично упорядоченного) файла не нужен большой стек, однако сортировка выполняется медленно, т.к. обрабатываемые подфайлы обычно имеют большой размер.

Возможны и дальнейшие улучшения алгоритма (например, можно использовать медиану из пяти или более элементов), но для случайно упорядоченных файлов сэкономленное время будет незначительным. Можно получить значительную экономию времени, переписав внутренние циклы (или всю программу) на ассемблере или в машинных кодах. Эти предложения были многократно проверены специалистами в солидных приложениях, использующих сортировку (см. раздел ссылок).

Программа 7.4. Усовершенствованная быстрая сортировка

Выбор медианы из первого, среднего и последнего элементов в качестве центрального элемента и отсечение рекурсии для небольших подфайлов может значительно повысить производительность быстрой сортировки. Данная реализация осуществляет разбиение по медиане из первого, среднего и последнего элементов массива (и иначе не включает их в процесс разбиения). Файлы длиной 11 и меньше игнорируются при разбиениях, а затем для завершения сортировки используется метод insertion из "Элементарные методы сортировки" .

  static const int M = 10;
  template <class Item>
  void quidcksort(Item a[], int l, int r)
    {
      if (r-1 <= M) return;
      exch(a[(l+r)/2], a[r-1]);
      comexch(a[l], a[r-1]);
      comexch(a[l], a[r]);
      comexch(a[r-1], a[r]);
      int i = partition(a, l+1, r-1);
      quicksort(a,l, i-1);
      quicksort(a, i+1, r);
    }
  template <class Item>
  void hybridsort(Item a[], int l, int r)
    { quicksort(a, l, r); insertion(a, l, r); }
        

Для случайно упорядоченных файлов первая перестановка в программе 7.4 не нужна. Она оставлена потому, что приводит к оптимальному разбиению уже упорядоченных файлов, а также потому, что служит защитой от нештатных ситуаций, которые могут встретиться на практике (см., например, упражнение 7.33). На рис. 7.11 иллюстрируется эффективность использования среднего элемента при определении места разбиения для файлов с различным начальным распределением ключей.

 Динамические характеристики быстрой сортировки с выбором медианы из трех для различных видов файлов

Рис. 7.11. Динамические характеристики быстрой сортировки с выбором медианы из трех для различных видов файлов

Вариант выбора медианы из трех (особенно при выборе среднего элемента файла) значительно повышает устойчивость процесса разбиения. Вырожденные виды файлов, показанные на рис. 7.4, обрабатываются очень хорошо. Другой вариант, достигающий той же цели - использование случайного центрального элемента.

Метод медианы из трех представляет собой специальный случай общего принципа: можно случайным образом выбрать записи из неизвестного файла и использовать свойства этой выборки для оценки свойств всего файла. В случае быстрой сортировки для получения сбалансированного разбиения нужно оценить медиану случайной выборки. Алгоритм таков, что нам не нужна очень точная оценка (или оценка вообще не нужна, если она требует больших вычислительных затрат); мы лишь хотим избежать очень неудачной оценки. Если для оценки используется случайная выборка лишь из одного элемента, получается вероятностный алгоритм, который почти наверняка выполняется быстро, независимо от входных данных. Если случайно выбрать из файла три или пять элементов, и затем использовать для разбиения их медиану, получится лучшее разбиение, но это усовершенствование будет достигнуто ценой выполнения и оценки выборки.

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

На больших случайно упорядоченных файлах быстрая сортировка (программа 7.1) работает почти в три раза быстрее, чем сортировка Шелла (программа 6.6). Отсечение небольших подфайлов и разбиение по медиане из трех (программа 7.4) еще более сокращают время сортировки.

Таблица 7.1. Эмпирическое сравнение алгоритмов быстрой сортировки
N Шелла Базовая быстрая сортировка Быстрая сортировка с разбиением по медиане из трех
M = 0 M = 10 M = 20 M = 0 M = 10 M = 20
12500 6 2 2 2 3 2 3
25000 10 5 5 5 5 4 6
50000 26 11 10 10 12 9 14
100000 58 24 22 22 25 20 28
200000 126 53 48 50 52 44 54
400000 278 116 105 110 114 97 118
800000 616 255 231 241 252 213 258

Упражнения

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

7.29. Реализуйте быструю сортировку, основанную на разбиении по медиане случайной выборки из пяти элементов файла. Элементы выборки не должны принимать участия в разбиении (см. упражнение 7.28). Сравните производительность полученного алгоритма с методом медианы из трех для больших случайно упорядоченных файлов.

7.30. Выполните программу из упражнения 7.29 для больших файлов со специальной организацией - например, для отсортированных файлов, файлов в обратном порядке или файлов с одинаковыми ключами. Как отличается ее производительность для этих файлов от производительности для случайно упорядоченных файлов?

7.31. Реализуйте быструю сортировку с использованием случайной выборки из 2k - 1

элементов. Сначала отсортируйте выборку, затем рекурсивной программой разбейте файл по медиане выборки, а оставшиеся половины выборки поместите в каждый подфайл так, чтобы они использовались в этих подфайлах без дальнейшей сортировки. Такой метод сортировки называется сортировкой методом случайной выборки (samplesort).

7.32. Определите эмпирическим путем наилучший размер выборки для сортировки

методом случайной выборки (см. упражнение 7.31) для N = 103, 104, 105 и 106 . Имеет ли значение, какой вид сортировки используется для упорядочения самой выборки: быстрая сортировка или сортировка методом случайной выборки?

7.33. Покажите, что если в программе 7.4 убрать первую перестановку и пропускать ключи, равные центральному, то время ее выполнения для обратно упорядоченных файлов будет квадратичным.

Бактыгуль Асаинова
Бактыгуль Асаинова

Здравствуйте прошла курсы на тему Алгоритмы С++. Но не пришел сертификат и не доступен.Где и как можно его скаачат?

Александра Боброва
Александра Боброва

Я прошла все лекции на 100%.

Но в https://www.intuit.ru/intuituser/study/diplomas ничего нет.

Что делать? Как получить сертификат?