【问题标题】:Stack overflow on recursive call of a function递归调用函数时的堆栈溢出
【发布时间】:2019-08-07 12:06:23
【问题描述】:

我正在尝试创建一个链排序算法,当我尝试再次递归调用它时,它给了我堆栈溢出错误

递归调用是我想将数组 a 排序为两个排序数组(preme,NoNpreme)的地方。之后我将这些合并回一个。 我试图弄乱条件,我发现当只有 1 个元素时数组是排序的,这就是我的递归出口。但它不起作用,我不知道为什么。

我的算法:

int* urediSPrameni(int* a, int n)
{
    if (n <= 1)
        return a;

    int pe=a[0];
    int* preme = new int[n];
    preme[0] = a[0];
    int j = 1;
    int k = 0;
    int* NoNpreme = new int[n];
    for(int i=0;i<n;i++)
    {
        if (a[i] > pe)
        {
            pe = a[i];
            preme[j] = a[i];
            j++;
        }
        else
        {
            NoNpreme[k] = a[i];
            k++;
        }
    }
    NoNpreme = urediSPrameni(NoNpreme, k);


    // My merge algorithm:

    //Zlivanje
    int h = 0;//NoNpreme
    int s = 0;//Preme
    int i = 0;
    while (h < k && s < j)
    {
            if (preme[h] <= NoNpreme[s])
            {
                a[i] = preme[h];
                s++;
            }
            else
            {
                a[i] = NoNpreme[s];
                h++;
            }
            i++;
    }
    if (h > k)
    {
        for (int b = s;b < j;b++)
        {
            a[i] = NoNpreme[b];
            i++;
        }
    }
    else
    {
        for (int b = h;b < k;b++)
        {
            a[i] = preme[b];
            i++;
        }
    }
    return a;
}

我这样调用函数:

int n = 7;
int drek[] = { 5,1,2,20,5,28,7 };
int* urejenoZap = urediSPrameni(drek, n);
for (int i = 0;i < n;i++)
    cout << urejenoZap[i] << " ";
system("PAUSE");

其中drek 是未排序的,urejenoZap 是指向已排序数组drek 的指针。

【问题讨论】:

  • NoNpreme = urediSPrameni(NoNpreme, k); 应该是return urediSPrameni(NoNpreme, k);
  • 它会泄漏大量内存,因为您没有delete[] 分配给new[] 的内存。
  • 好的。所以我在 return 之前删除了数组 1 行并将 return NoNpreme = urediSPrameni(NoNpreme, k) 但它仍然溢出。
  • @πάνταῥεῖ 我认为合并部分是同一功能的延续。在这个地方返回会导致函数的其余部分永远无法到达。
  • 那么我该如何修复呢?

标签: c++ function recursion stack-overflow


【解决方案1】:

您将a 的第一个元素分配给pe,并将该元素的副本存储到preme。当根据pe 的哪一侧将a 的元素排序到单独的数组中时,您再次从元素0 开始(您已经将其放入preme),因为if (a[i] &gt; pe) 将是false,会将这个元素放入NoNpreme。一旦数组到达有多个元素且第一个元素最小的点,所有元素将被复制到NoNpreme。之后的每个递归调用都将执行相同的操作,因此递归将永远不会结束,您最终会耗尽堆栈空间。

解决方案是用第二个元素开始你的 for 循环:

for (int i = 1; i < n; i++)

【讨论】:

    猜你喜欢
    • 2018-05-28
    • 2017-10-20
    • 2013-02-22
    • 2019-02-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-26
    相关资源
    最近更新 更多