Блог пользователя alexlampdeveloper

Автор alexlampdeveloper, 9 лет назад, По-русски

Добрый вечер, всем жителям CodeForces!=) Я помню, что когда-то прочитал такую интересную статейку, что sort() в плюсах работает чуть быстрее за n*log(n). И мне теперь стало интересно правда ли это? Если да, то не подскажете по какому алгоритму он работает?

  • Проголосовать: нравится
  • -8
  • Проголосовать: не нравится

»
9 лет назад, # |
Rev. 3   Проголосовать: нравится +5 Проголосовать: не нравится

Стандартом не оговаривается какой именно алгоритм должен быть под капотом std::sort. Однако можно подглядеть как реализован std::sort, например, в gcc.

Там работает QuickSort, который переключается на HeapSort если глубина рекурсии превышает 2 логарифма от количества элементов. Также для количества элементов меньше 16 включается сортировка вставками. Опорный элемент для QuickSort выбирается как медиана из первого, последнего и элемента посередине.

Сложность сей конструкции всё равно N * Log(N)

»
9 лет назад, # |
Rev. 3   Проголосовать: нравится +5 Проголосовать: не нравится

Introsort. Сначала quicksort, но если глубина рекурсии слишком большая, переключается на heap sort; таким образом, сложность равна O(n log n) и в среднем, и в худшем случае, но в среднем случае используется самый быстрый алгоритм с этой сложностью. Плюс для пущей скорости на маленьких отрезках делается ни то и ни другое, а insertion sort (но это не влияет на асимптотику).

Как отметили выше, стандарт не оговаривает конкретный алгоритм, но сложность обязательно должна быть O(n log n). Таким образом, простой quicksort недопустим (потому что у него в худшем случае n²), но разрешается не только introsort, но и, например, heap sort, merge sort или ещё что-нибудь более экзотическое. Однако на практике introsort быстрее всего и поэтому используется именно он.

  • »
    »
    9 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится +14 Проголосовать: не нравится

    Полагаю, что доп.память использовать он тоже не может(точнее не должен падать, если памяти не хватает) и поэтому mergesort не пойдет.

    • »
      »
      »
      9 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      А, ну да, ведь in-place merge sort уже не n log n. Действительно.

  • »
    »
    9 лет назад, # ^ |
      Проголосовать: нравится +10 Проголосовать: не нравится

    Ещё стоит отметить, что это зависит от версии C++: O(n log n) в худшем случае требуется только начиная с C++11, а до того было достаточно в среднем.