[英]Runtime errors in C++ implementation of quicksort
我正在編寫quicksort的實現,以提高我的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;
}
}
我相信您的錯誤之一是主要的這一行:
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
。 因此,當你調用遞歸quicksort
的greater
,你最終會遞歸地嘗試理清你開始使用,導致無限遞歸完全相同的范圍。
要解決此問題,請嘗試更新代碼,以便將您分成三組-小於樞軸的元素,大於樞軸的元素以及等於樞軸的元素。 您仍將在較小和較大的范圍上進行遞歸,但不會在相等的值上遞歸調用自己。 這樣可以確保遞歸總是在比開始時小的范圍內調用。
最后,正如其他人指出的那樣,您的當前實現會泄漏大量內存,因為您永遠不會釋放所構造的任何臨時數組。 為避免這種情況,請考慮將原始數組的使用替換為std::vector
,它執行自己的內存管理並且不會泄漏任何內存。 另外,由於您可以僅使用push_back
追加元素,因此可以大大簡化將數組拆分為區域的操作。
希望這可以幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.