C++ 快速排序/向量/分区问题

C++ 快速排序/向量/分区问题,c++,stl,quicksort,data-partitioning,C++,Stl,Quicksort,Data Partitioning,我对以下代码有问题: class quicksort { private: void _sort(double_it begin, double_it end) { if ( begin == end ) { return ; } double_it it = partition(begin, end, bind2nd(less<double>(), *begin)) ; iter_swap(begin, it-1); _sort(begin,

我对以下代码有问题:

class quicksort {
private:
  void _sort(double_it begin, double_it end)
  {
    if ( begin == end ) { return ; }
    double_it it = partition(begin, end, bind2nd(less<double>(), *begin)) ;
    iter_swap(begin, it-1);
    _sort(begin, it-1);
    _sort(it, end);
  }
public:
  quicksort  (){}
  void operator()(vector<double> & data)
  {
    double_it begin = data.begin();
    double_it end = data.end() ;
    _sort(begin, end);
  }
};
类快速排序{
私人:
void\u排序(双倍开始,双倍结束)
{
如果(begin==end){return;}
double_it it=partition(begin,end,bind2nd(less(),*begin));
国际热核实验堆交换(begin,it-1);
_排序(开始,it-1);
_排序(it,end);
}
公众:
快速排序(){}
void运算符()(向量和数据)
{
double_it begin=data.begin();
double_it end=data.end();
_排序(开始、结束);
}
};
但是,这对太多的元素不起作用(它适用于10000个元素,但不适用于100000个)

示例代码:

int main()
{
  vector<double>v ;

  for(int i = n-1; i >= 0 ; --i)
    v.push_back(rand());  

  quicksort f;
  f(v);

  return 0;
}
intmain()
{
向量;
对于(int i=n-1;i>=0;--i)
v、 向后推(rand());
快速排序f;
f(v);
返回0;
}
STL分区函数不适用于这样的大小吗?还是我遗漏了什么


非常感谢您的帮助。

您是否检查了您的
doublt\it
是否未设置为
开始
的值?这将导致线路
iter_交换(begin,it-1)出现问题

不是吗


好的,我猜#2是堆栈溢出,因为您将进入太多的递归。某些编译器不能处理许多递归循环。10万可能就够了,而10万可能就够了。

我发现了几个问题。我不会在分区中包含pivot,因此我将使用这一行:

double_it it = partition(begin + 1, end, bind2nd(less<double>(), *begin)) ;
相反,但是您需要注意的是
it-2
不小于
begin
,因此请检查
it-1!=首先开始
。无需持续对枢轴进行排序-它已经位于正确的位置。这只会增加很多额外的不必要的递归


即使在更改之后,此代码仍然可能存在堆栈溢出问题。例如,如果使用此代码对已排序的数组进行排序,则性能将为O(N^2),如果N非常大,则会出现堆栈溢出。使用随机选择的枢轴基本上可以消除排序数组的问题,但如果数组都是相同的元素,则仍然可能存在问题。在这种情况下,您需要更改算法以使用Bentley McIlroy分区或类似的方法。或者,当递归深度变得非常深时,您可以将其更改为introsort并更改为heapsort

检查以下代码。我写得很快,没有模板和使用迭代器,但目的是证明快速排序可以对大型数组进行排序(他说,这很明显)

因此,您的快速排序在算法方面有问题,而不是在堆栈溢出/其他编译器方面。我的意思是,您应该始终尝试了解是什么导致了什么,并消除“深”问题,而不是“浅”问题。

请注意,我的代码可以使用与代码中相同的迭代器方法轻松重写(可能需要一些额外的检查,但无论如何,它很容易实现)


定义“不会工作”它编译失败了吗?跑不动?崩溃给出错误的结果?什么?有什么原因不能使用
std::sort
?我刚刚尝试添加一个测试{if(首次登场!=it){iter_swap(首次登场,it-1);}}},但这不会改变失败。您是否遇到堆栈溢出问题?我不相信C++在某些编译器中能处理大量的递归。我已经尝试在一个Ty{{ } catch(…){CUT中括上了一个类排序体。
_sort(begin, it - 2);
#include <vector>
#include <algorithm>
#include <utility>
#include <functional>

class sorter {
public:
   sorter(std::vector<int>& data) : data(data) { }

   void quicksort(int p, int r) {
      if (p < r) {
         int q = std::partition(data.begin() + p, data.begin() + r, std::bind2nd(std::less<int>(), data[r])) - data.begin();
         std::swap(data[q], data[r]);
         quicksort(p, q - 1);
         quicksort(q + 1, r);
      }
   }

   void sort() {
      quicksort(0, data.size() - 1);
   }

private:
   std::vector<int>& data;
};

int main() {
   size_t n = 1000000;
   std::vector<int> v;

   for(int i = n - 1; i >= 0 ; --i)
      v.push_back(rand());  

   sorter s(v);
   s.sort();

   return 0;
}
class sorter {
public:
   typedef std::vector<int> data_type;
   sorter(std::vector<int>& data) : data(data) { }

   void quicksort(data_type::iterator p, data_type::iterator r) {
      data_type::iterator q = std::partition(p, r, std::bind2nd(std::less<int>(), *r));
      std::iter_swap(q, r);

      if (q != p)
         quicksort(p, q - 1);
      if (q != r)
         quicksort(q + 1, r);
   }

   void sort() {
      quicksort(data.begin(), data.end() - 1);
   }

private:
   std::vector<int>& data;
};