Это отличает его от std::sort
list
.Концепция сортировки очень проста, но есть несколько вариаций на тему ее реализации в стандартной библиотеке. Следующий перечень описывает эти вариации.
partial_sort
Принимает три итератора произвольного доступа — first
middle
и last
— и (необязательно) функтор сравнения. Он имеет два постусловия: элементы диапазона (first
, middle
) будут меньше, чем элементы диапазона (middle
, last
), и диапазон (first
, middle
) будет отсортирован с помощью operator<
или указанного функтора сравнения. Другими словами, он сортирует только первые partial_sort_сору
Делает то же, что и partial_sort
nth_element
Принимает три итератора произвольного доступа — first
nth
и last
— и необязательный функтор сравнения. Он помешает элемент, на который ссылается nth
, в то место, где он находился бы, если бы весь диапазон был отсортирован. Следовательно, все элементы диапазона (first
, nth
) будут меньше, чем элемент в позиции nth
(те, что находятся в диапазоне (nth
, last
) не сортируются, но больше, чем те, что предшествуют nth
). Этот алгоритм следует использовать тогда, когда требуется отсортировать только один или несколько элементов диапазона и избежать затрат на сортировку всего диапазона.Также можно разделить элементы диапазона в соответствии с каким-либо критерием (функтором), и это является предметом обсуждения рецепта 7.7.
Рецепт 7.7.
7.7. Разделение диапазона
Имеется диапазон элементов, которые требуется каким-либо образом разделить на группы. Например, необходимо переместить в начало диапазона все элементы, которые меньше определенного значения.
Для перемещения элементов используйте стандартный алгоритм partition
#include
#include
#include
#include
#include
#include
#include
#include "utils.h" // Для printContainer(): см. рецепт 7.10
using namespace std;
int main() {
cout << "Введите набор строк: ";
istream_iterator
istream_iterator
vector
// Реорганизуем элементы в v так, чтобы те, которые меньше,
// чем "foo", оказались перед остальными.
vector
partition(v.begin(), v.end(),
bind2nd(less
printContainer(v);
cout << "*p = " << *p << endl;
}
Вывод примера 7.7 выглядит примерно так.
Введите набор строк: a d f j k l
^Z
-----
a d f j k l
*p = j
После работы partition
p
указывает на первый элемент, для которого less(*p, "foo")
не равно true
.partition
true
, в начало диапазона. Он возвращает итератор, указывающий на первый элемент, для которого предикат не равен true
, или на конец диапазона, если все элементы удовлетворяют предикату. Он объявлен вот так.Bi partition(Bi first, Bi last, Pred pred);
pred
true
или false
. Предиката по умолчанию не существует — вы должны указать такой предикат, который удовлетворяет требованию разделения диапазона. При этом можно написать свой предикат, а можно использовать один из предикатов стандартной библиотеки. Например, в примере 7.7 можно видеть, что я для создания функтора использовал less
и bind2nd
.vector
partition(v.begin(), v.end(),
bind2nd(less