C++ 如何以稳定的方式进行部分排序
C++ 如何以稳定的方式进行部分排序,c++,sorting,C++,Sorting,std::partial_sort是否稳定,如果不稳定,是否有标准库或boost提供的稳定的部分排序?partial_sort是高效且易于提供的,因为它基本上是一种快速排序,可以跳过所需范围内不需要的递归。没有等效有效的部分稳定排序算法stable_sort通常作为合并排序实现,而合并排序的递归工作方式是错误的 如果希望部分排序保持稳定,则需要将位置信息与每个元素相关联。如果您有一个可修改的zip范围,您可以通过将元素和iota向量压缩在一起来实现这一点,但是在当前迭代器的概念中,实际上不可能构
std::partial_sort
是否稳定,如果不稳定,是否有标准库或boost提供的稳定的部分排序?partial_sort
是高效且易于提供的,因为它基本上是一种快速排序,可以跳过所需范围内不需要的递归。没有等效有效的部分稳定排序算法stable_sort
通常作为合并排序实现,而合并排序的递归工作方式是错误的
如果希望部分排序保持稳定,则需要将位置信息与每个元素相关联。如果您有一个可修改的zip范围,您可以通过将元素和iota向量压缩在一起来实现这一点,但是在当前迭代器的概念中,实际上不可能构建可修改的zip范围,因此通过迭代器进行间接排序和依赖迭代器的排序更容易。换句话说,您可以这样做:
using MyThingV = std::vector<MyThing>;
using MyThingIt = typename MyThingV::iterator;
MyThingV things;
// Set up a vector of iterators. We'll sort that.
std::vector<MyThingIt> sorted; sorted.reserve(things.size());
for (auto it = things.begin(); it != things.end(); ++it) sorted.push_back(it);
std::partial_sort(sorted.begin(), sorted.begin() + upto_index, sorted.end(),
[](MyThingIt lhs, MyThingIt rhs) {
// First see if the underlying elements differ.
if (*lhs < *rhs) return true;
if (*rhs < *lhs) return false;
// Underlying elements are the same, so compare iterators; these represent
// position in original vector.
return lhs < rhs;
});
使用MyThingV=std::vector;
使用MyThingIt=typename MyThingV::iterator;
虚构事物;
//设置一个迭代器向量。我们会解决的。
std::向量排序;sorted.reserve(things.size());
对于(auto-it=things.begin();it!=things.end();++it)排序。向后推(it);
std::partial_sort(sorted.begin(),sorted.begin()+upto_index,sorted.end(),
[](MyThingIt lhs、MyThingIt rhs){
//首先看看基础元素是否不同。
如果(*lhs<*rhs)返回true;
如果(*rhs<*lhs)返回false;
//底层元素是相同的,所以比较迭代器;它们表示
//在原始向量中的位置。
返回左侧<右侧;
});
现在,基本向量仍然未排序,但迭代器的向量是按您想要的方式排序的。它不是(保证)稳定的。我想补充一点,另一种不太灵活的方法,但在某些情况下可能是一种很好的替代方法,即使用
std::vector
并用唯一的数字填充对的秒数(如原始索引)。然后,您也可以在没有自定义比较器的情况下实现稳定的部分排序。不使用迭代器,您是否可以使用自定义的less函数来比较两个对象的地址(如果它们相等)?对于向量,地址的相对顺序与向量索引的顺序相同。因此,您可以省略迭代器的向量。@Fab伊恩No,因为排序过程中位置发生变化。考虑在代码> > [5,3,1,1 ]上的快速排序分区阶段。以3
为轴心。它首先将5
与3
和1'
与3
进行比较。两者都在错误的一边,因此它们被交换。现在1'
在序列中比1
更早,因此比较更少,这正是我们不想要的。