递归函数导致堆栈溢出

时间:2017-10-20 02:04:28

标签: c++ recursion

我遇到了一个问题,我的功能是在1和0的迷宫中找到路径,如果它在该路径上或者找到了退出,则返回true,如果迷宫无法解析,则返回false。每当我尝试检查" - 1s"时,我都会收到堆栈溢出错误。我的变量,但我的基本情况应该是防止这种情况。有没有办法减少堆栈空间与递归?这是我的代码

bool Pathfinder::check(string& maze, stack<string>& path, int x, int y, int z) 
{int checking = 0;
    if ((x == 4) && (y == 4) && (z == 4))
    {
        path.push(this->createCoords(x, y, z));
        return true;
    }
    else
    {
        if ((x + 1) < 1 || (x + 1) > columns)
        {
            return false;
        }
        if ((y + 1) < 1 || (y + 1) > rows)
        {
            return false;
        }
        if ((z + 1) < 1 || (z + 1) > floors)
        {
            return false;
        }
        if ((x < 0) || (y < 0) || (z < 0))
        {
            return false;
        }
        if (this->getValue(maze, x, y, z) == 1)
        {
            this->setValue(maze, x, y, z, 2);
        }
        else
        {
            return false;
        }
    }


    if (this->check(maze, path, x + 1, y, z) ||
        this->check(maze, path, x, y + 1, z) ||
        this->check(maze, path, x, y, z + 1))
    {
        checking++;
    }
    if (this->check(maze, path, x - 1, y, z) && checking == 1) //Overflow error comes from here
    {
        checking++;
    }
    if (this->check(maze, path, x, y - 1, z) && checking == 2)
    {
        checking++;
    }
    if (this->check(maze, path, x, y, z - 1) && checking == 3)
    {
        path.push(this->createCoords(x, y, z));

        return true;
    }

    return false;
}

1 个答案:

答案 0 :(得分:1)

你不能使用&#34;更少的堆栈空间&#34;原因很简单,当所需的堆栈空间量是无限的时,任何小于无限的东西仍然是无限的。这就是无限意味着什么。所示算法在逻辑上是有缺陷的,并且显然导致无限递归。让我们为这些递归调用标记如下:

if (this->check(maze, path, x + 1, y, z) ||   // A
    this->check(maze, path, x, y + 1, z) ||   // B
    this->check(maze, path, x, y, z + 1))     // C
{
    checking++;
}

if (this->check(maze, path, x - 1, y, z) && checking == 1) // D
{
    checking++;
}

checking的初始值为0.我们可以根据上述代码得出以下结论。

1)总是发生递归调用A

2)有一组坐标,其中A,B或C递归的cals返回true

3)当条件2)成立时,总是会发生递归调用D

因此,无论什么条件&#34; 2)&#34;是的,这保证了无限递归。递归调用A然后进行递归调用D在逻辑上是无限递归。

这是因为在递归调用之前导致条件2)为真,递归调用A传递x+1。并且在递归调用条件内&#34; 2)&#34;计算结果为true,这将导致递归调用D.

但是这导致两个连续的嵌套递归调用,首先传递x+1,然后传递x+1-1第二个,具有相同的yz值。然后,第二个递归调用将xyz的相同值作为其祖父母调用传递,并且此处没有任何内容可以阻止此无限递归。

显示的算法从根本上被打破。您需要弄清楚它为什么会被破坏,以及什么是正确的算法。这是无法根据问题中有限的信息来回答的,唯一能够轻易确定的是原因,以及无限递归发生的原因;这很明显。