【发布时间】:2014-02-10 23:34:38
【问题描述】:
在开始之前,我只想说我在过去 2 个小时左右的时间里阅读了关于“快速排序”和“堆栈溢出”的 SO 帖子,所以我不只是随机询问,我真的不知道怎么办……
好的,我必须实现一个快速排序算法,但由于某种原因我找不到,我不断收到堆栈溢出错误。我用的是VS2010,所以从头到尾调试过。
所以,这是我的代码:
const int THRESHOLD = 1;
std::vector<int> data = *new std::vector<int>();
void GetPivotPoint( bool first, int leftBound, int rightBound, int& pivotID )
{
if( first ) // We are choosing the first element as a pivot
{
pivotID = 0;
return;
}
else // We are choosing the median between 1, n/2 and n for our pivot
{
int left = leftBound;
int right = rightBound;
int center = ( left + right ) / 2;
if( data[center] - data[left] < 0 ) data_manip::Swap( data, left, center );
if( data[right] - data[left] < 0 ) data_manip::Swap( data, left, right );
if( data[right] - data[center] < 0 ) data_manip::Swap( data, center, right );
data_manip::Swap( data, center, right );
pivotID = right;
}
}
int Partition( int left, int right )
{
int pivotID = 0;
GetPivotPoint( true, left, right, pivotID );
int pivot = data[pivotID];
int i = left - 1;
int j = right + 1;
while( i < j )
{
i++;
while( data[i] < pivot ) i++;
j--;
while( data[j] > pivot ) j--;
if( i < j )
{
data_manip::Swap( data, i, j );
}
}
return j;
}
void Quicksort( int left, int right )
{
if( left + THRESHOLD > right )
{
algo::Bubblesort( data, left, right );
}
else
{
int partitionPoint = Partition( left, right );
Quicksort( left, partitionPoint );
Quicksort( partitionPoint + 1, right );
}
}
这是 Swap() 方法的实现
inline void Swap( std::vector<int>& data, int p1, int p2 )
{
int temp = data[p1];
data[p1] = data[p2];
data[p2] = temp;
}
我正在使用超过 1k 到 500K 的集合。另外,在这个特定的代码中,我使用了将第一个元素作为枢轴的选项,现在我知道这不是最佳的,但我也需要测试该选项。如果我确实使用三的中位数而不是第一个元素,那么我不会得到堆栈溢出,但是,当我使用第一个元素作为枢轴时可能会导致它。
帮助的坦克
【问题讨论】:
-
“由于某种原因我找不到” - 这将是递归。堆栈的大小是有限的,每个递归调用都会吃掉它的一部分。 (使用三的中位数,您不太可能遇到快速排序的病态最坏情况,因此不太可能递归太深。)
-
这是为了你自己的学习目的吗?否则,
std::sort. -
Knuth 和 Sedgewick 都提到最好先在较小的分区上递归,以节省堆栈增长。大多数实现使用低于阈值的插入排序。在这个或任何其他应用程序中,冒泡排序没有什么可推荐的。
-
以下不是堆栈溢出的来源,而是错误代码和内存泄漏。当您创建
vector时,只需执行std::vector<int> data;即可。您使用new的方式是内存泄漏和非常奇怪的做法。