簡體   English   中英

快速排序的C ++實現中的運行時錯誤

[英]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 因此,當你調用遞歸quicksortgreater ,你最終會遞歸地嘗試理清你開始使用,導致無限遞歸完全相同的范圍。

要解決此問題,請嘗試更新代碼,以便將您分成三組-小於樞軸的元素,大於樞軸的元素以及等於樞軸的元素。 您仍將在較小和較大的范圍上進行遞歸,但不會在相等的值上遞歸調用自己。 這樣可以確保遞歸總是在比開始時小的范圍內調用。

最后,正如其他人指出的那樣,您的當前實現會泄漏大量內存,因為您永遠不會釋放所構造的任何臨時數組。 為避免這種情況,請考慮將原始數組的使用替換為std::vector ,它執行自己的內存管理並且不會泄漏任何內存。 另外,由於您可以僅使用push_back追加元素,因此可以大大簡化將數組拆分為區域的操作。

希望這可以幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM