tl; dr: Можно ли эффективно реализовать быструю сортировку в двусвязном списке? Мое понимание, прежде чем думать об этом, было, нет, его нет.
На днях у меня была возможность рассмотреть требования к итераторам для основных алгоритмов сортировки. Основные O (N²) довольно просты.
- Bubble sort - 2 итератора вперед будут работать хорошо, один перетаскивая за другим.
- Сортировка вставок - подойдут 2 двунаправленных итератора. Один для элемента, вышедшего из строя, другой для точки вставки.
- Сортировка выбора - немного хитрее, но передовые итераторы могут сделать свое дело.
Quicksort
introsort_loop в std :: sort (как в стандартной библиотеке gnu / hp (1994) / кремниевой графике (1996)) требует, чтобы он был random_access.
__introsort_loop(_RandomAccessIterator __first,
_RandomAccessIterator __last,
_Size __depth_limit, _Compare __comp)
Как я и ожидал.
Теперь при ближайшем рассмотрении я не могу найти реальную причину, чтобы потребовать это для быстрой сортировки. Единственное, что явно требует random_access_iterators - это вызов std::__median
, который требует вычисления среднего элемента. Обычная ванильная быстрая сортировка не не вычисляет медиану.
Разделение состоит из чека
if (!(__first < __last))
return __first;
Не очень полезная проверка для двунаправленных сообщений. Тем не менее, можно заменить это проверкой в предыдущем ходе разбиения (слева направо / справа налево) с простым условием
if ( __first == __last ) this_partitioning_is_done = true;
Возможно ли реализовать быструю сортировку достаточно эффективно, используя только двунаправленные итераторы? Рекурсивная глубина все еще может быть защищена.
NB. Я еще не пытался фактической реализации.