Daily bit(e) C++. std::partial_sort_copy

Добавлено 25 августа 2026 в 22:51

Daily bit(e) C++ 87, алгоритм частичной сортировки, не требующий, чтобы исходный диапазон предоставлял произвольный доступ к элементам: std::partial_sort_copy.

Daily bit(e) C++

std::partial_sort_copy – необычный алгоритм сортировки. Он не требует произвольного доступа к элементам в исходном диапазоне, обеспечивая при этом сложность выполнения O(n*logk).

Алгоритм «копирует» верхние k элементов в выходной диапазон (который должен быть с произвольным доступом) в отсортированном порядке.

Сортировка нестабильна, т.е. не сохраняет порядок равных элементов.

Доступны как параллельная версия из C++17, так и версия для диапазонов из C++20.

#include <forward_list>
#include <string>
#include <string_view>
#include <vector>
#include <algorithm>


std::forward_list<std::string> names{
  "Emma", "Liam", "Zara", "Ethan", "Aria", "Mateo", "Ivy", "Finn",
  "Luna", "Kai", "Mila", "Oscar", "Ruby", "Levi", "Nora"};

// Размер выходного диапазона определяет количество 
// копируемых/сортируемых элементов
std::vector<std::string> out1(3);

std::partial_sort_copy(
    names.begin(), names.end(), // исходный диапазон
    out1.begin(), out1.end());  // целевой диапазон
// out1 == {"Aria", "Emma", "Ethan"}


std::vector<std::string> out2(5);

std::partial_sort_copy(
    names.begin(), names.end(), // исходный диапазон
    out2.begin(), out2.end(),   // целевой диапазон
    std::greater<>{});          // пользовательский компаратор
// out2 == {"Zara", "Ruby", "Oscar", "Nora", "Mila"}


std::vector<std::string> out3(4);

// версия для диапазонов
auto length = [](const std::string& s) { return s.length(); };
std::ranges::partial_sort_copy(names, out3, // диапазоны
    std::greater<>{}, // пользовательский компаратор
    length,           // проекция для исходного диапазона
    length);          // проекция для диапазона назначения
// out3 ~= {"Oscar", "Mateo", "Ethan", "Zara"}


// Из-за раздельных проекций в целевом диапазоне могут
// использоваться элементы другого типа.

std::vector<std::string_view> out4(4);

auto view_len = [](const std::string_view& s) { return s.length(); };
std::ranges::partial_sort_copy(names, out4, // диапазоны
    std::greater<>{}, // greater поддерживает сравнение std::string/std::string_view
                      // без преобразований
    length,           // проекция для std::string
    view_len);        // проекция для std::string_view
// out4 ~= {"Oscar", "Mateo", "Ethan", "Zara"}

Пример на Compiler Explorer

Теги

C++ / CppDaily bit(e) C++Программирование