快速排序的 C++ 实现中的运行时错误
Posted
技术标签:
【中文标题】快速排序的 C++ 实现中的运行时错误【英文标题】:Runtime errors in C++ implementation of quicksort 【发布时间】:2011-08-23 23:32:34 【问题描述】:我正在编写一个快速排序的实现来提高我的 C++ 技能,但是我遇到了一个让我很困惑的错误。该算法似乎在大约 25% 的时间内运行良好,但在另外 75% 的时间里我一直遇到错误,程序报告分段错误或堆栈溢出。如果有人可以提供帮助,将不胜感激。提前致谢。
#include <iostream>
#include <string.h>
#include <ctime>
using namespace std;
#define size 20
void printSet(int* set);
int* quicksort(int* set, int l);
int* concat(int* less, int countL, int* greater, int countG);
int main()
srand(time(NULL));
int* set;
set = new int[size];
for(int i=0; i<size; i++)
set[i]=rand()%200;
printSet(set);
set = quicksort(set, size);
printSet(set);
delete set;
int i;
cin>> i;
return 0;
int* quicksort(int* set, int l)
//cout<<"QS\n";
if (l <= 1)
return set;
int* less = new int[l];
int* greater = new int[l];
int pivotIndex = rand() % l,
pivotVal = set[pivotIndex],
countL = 0,
countG = 0;
for(int i=0; i<l; i++)
if (set[i] < pivotVal)
less[countL++]=set[i];
else
greater[countG++]=set[i];
set = concat(quicksort(less, countL), countL, quicksort(greater, countG), countG);
return set;
int* concat(int* less, int countL, int* greater, int countG)
//cout<<"concat\n";
int* set;
set = new int[size];
int i;
for(i=0; i<countL; i++)
set[i]=less[i];
for(int j=0; j<countG; j++)
set[i+j]=greater[j];
return set;
void printSet(int* set)
cout<<"******************\nPrinting Set\n";
for(int i=0; i< size; i++)
cout<<i<<": "<<set[i]<<endl;
【问题讨论】:
错误到底是什么意思? 错误是什么?尝试使用调试器单步执行。 您的quicksort
函数和concat
函数也存在内存泄漏。
你的越来越小的数组也永远不会被删除。在大型数据集上,这可能会泄漏大量内存。编辑:打败它
我刚刚编辑了问题以包括报告了哪些错误(我在我的机器上运行了几次)。希望这可以澄清事情!
【参考方案1】:
我相信你的错误之一是在 main 的这一行:
delete set;
这里的问题是set
是一个用new[]
分配的数组。要释放它的内存,您需要通过对delete[]
的匹配调用来删除它。这可以通过将行重写为来解决
delete[] set;
此外,您的代码在某些情况下有机会无限递归。特别是,假设您尝试对包含两个 0 副本的列表进行排序。在这种情况下,请考虑以下代码将做什么:
for(int i=0; i<l; i++)
if (set[i] < pivotVal)
less[countL++]=set[i];
else
greater[countG++]=set[i];
set = concat(quicksort(less, countL), countL, quicksort(greater, countG), countG);
由于您的枢轴元素为 0(这是唯一的选择!),您将遍历数组并将数组中的两个 0 放入 greater
。因此,当您在 greater
上递归调用 quicksort
时,您最终将递归地尝试对开始时完全相同的范围进行排序,从而导致无限递归。
要解决此问题,请尝试更新您的代码,以便将您分成三组 - 小于枢轴的元素、大于枢轴的元素和等于枢轴的元素。您仍然会在更小和更大的范围上递归,但您不会在相等的值上递归调用自己。这将确保始终在比您开始时更小的范围内调用递归。
最后,正如其他人所指出的,您当前的实现会泄漏大量内存,因为您从未释放任何您构建的临时数组。为避免这种情况,请考虑将您对原始数组的使用替换为 std::vector
,它自己进行内存管理并且不会泄漏任何内存。此外,它还使得将数组拆分为区域变得更加容易,因为您只需使用 push_back
来追加元素。
希望这会有所帮助!
【讨论】:
我编译了代码,但由于您所描述的,他正在发生堆栈溢出。 +1 @Seth Carnegie- 是的,我用 gdb 和 valgrind 运行它来发现这些错误。我希望我抓住了一切! 所以这就是为什么 OP 认为没有必要发布错误消息。 感谢大家的帮助!我真的很感激。 @Luke- 很高兴能帮上忙!如果这回答了您的问题,请务必将答案标记为已接受以标记问题已解决。以上是关于快速排序的 C++ 实现中的运行时错误的主要内容,如果未能解决你的问题,请参考以下文章