一:功能
部分排序,即选出前n个最大值或者最小值,剩余部分是无序的。
二:用法
#include <vector>
#include <algorithm>
#include <iostream>
int main() {
std::vector<int> data{9, 8, 7, 6, 5, 4, 3, 2, 1};
std::partial_sort(data.begin(), data.begin()+3, data.end());
for (auto v : data) {
std::cout << v << " ";
}
std::cout << "\n";
std::ranges::partial_sort(data, data.begin()+3, std::greater<>());
for (auto v : data) {
std::cout << v << " ";
}
std::cout << "\n";
}
三:实现
#include <algorithm>
#include <array>
#include <functional>
#include <iostream>
namespace impl
{
template<typename RandomIt, typename Compare>
constexpr //< since C++20
void sift_down(RandomIt first, RandomIt last, const Compare& comp)
{
// sift down element at “first”
const auto length = static_cast<std::size_t>(last - first);
std::size_t current = 0;
std::size_t next = 2;
while (next < length)
{
if (comp(*(first + next), *(first + (next - 1))))
--next;
if (!comp(*(first + current), *(first + next)))
return;
std::iter_swap(first + current, first + next);
current = next;
next = 2 * current + 2;
}
--next;
if (next < length && comp(*(first + current), *(first + next)))
std::iter_swap(first + current, first + next);
}
template<typename RandomIt, typename Compare>
constexpr //< since C++20
void heap_select(RandomIt first, RandomIt middle, RandomIt last, const Compare& comp)
{
std::make_heap(first, middle, comp);
for (auto i = middle; i != last; ++i)
{
if (comp(*i, *first))
{
std::iter_swap(first, i);
sift_down(first, middle, comp);
}
}
}
} // namespace impl
template<typename RandomIt, typename Compare>
constexpr //< since C++20
void my_partial_sort(RandomIt first, RandomIt middle, RandomIt last, Compare comp)
{
impl::heap_select(first, middle, last, comp);
std::sort_heap(first, middle, comp);
}
void print(const auto& s, int middle)
{
for (int a : s)
std::cout << a << ' ';
std::cout << '\n';
if (middle > 0)
{
while (middle-- > 0)
std::cout << "--";
std::cout << '^';
}
else if (middle < 0)
{
for (auto i = s.size() + middle; --i; std::cout << " ")
{}
for (std::cout << '^'; middle++ < 0; std::cout << "--")
{}
}
std::cout << '\n';
};
int main()
{
std::array<int, 10> s{5, 7, 4, 2, 8, 6, 1, 9, 0, 3};
print(s, 0);
my_partial_sort(s.begin(), s.begin() + 3, s.end(), std::less{});
print(s, 3);
my_partial_sort(s.rbegin(), s.rbegin() + 4, s.rend(), std::less{});
print(s, -4);
my_partial_sort(s.rbegin(), s.rbegin() + 5, s.rend(), std::greater{});
print(s, -5);
}