Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何以稳定的方式进行部分排序_C++_Sorting - Fatal编程技术网

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
更早,因此比较更少,这正是我们不想要的。