algosy

RandomizedQuickSort(c):
     if |c| <= 1: # тут и сортировать нечего
        return c
     m = random_choice(c) # выбираем случайный элемент из массива
     определяем элементы c_small меньшие m 
     определяем элементы c_large большие m
     RandomizedQuickSort(c_small) # рекурсивный вызов алгоритма
     RandomizedQuickSort(c_large)
     объединяем c_small, m и c_large в итоговый массив c_sorted
     return c_sorted

В этом псевдокоде подразумевается, что все элементы массива разные. Ожидаемое время выполнения алгоритма составляет .

Алгоритм легко изменить для случая, когда в этом массиве есть повторы. Чтобы это сделать, пусть в содержатся все элементы со значением не более , а не элементы со значением менее . Тем не менее такая модификация становится медленной даже относительно ожидаемого времени выполнения. Например, если все элементы одинаковы, разделяется на две части: размер составляет , а в нет элементов. Так как это разделение требует от RandomizedQuickSort времени , общее время выполнения составляет:

то есть вместо .

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

  • Формат ввода: Первая строка содержит целое число . В следующей строке содержится последовательность из целых чисел .
  • Формат вывода: Вывод последовательности в неубывающем порядке.
  • Ограничения: ; для всех .

Пример:

Ввод

Вывод

5
2 3 9 2 2

2 2 2 3 9

  • Совет: не используйте встроенные алгоритмы сортировки.

Решение

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

✒️ Упражнение:
Продемонстрируйте, как разделить массив на три части (меньше опорного элемента m, равняется ему и больше него) на месте — без использования дополнительной памяти.

Отмечайте параграфы как прочитанные чтобы видеть свой прогресс обучения

Вступайте в сообщество хендбука

Здесь можно найти единомышленников, экспертов и просто интересных собеседников. А ещё — получить помощь или поделиться знаниями.
Вступить
Сообщить об ошибке
Предыдущий параграф7.2. Поиск доминирующего элемента
Следующий параграф7.4. Подсчёт инверсий