-2

我已经实现了可以在这个链接下找到的递归算法。当 3d 数组为 10x10x10 时,它工作得很好。

我试图让它运行 200x200x200 数组但是,Visual Studio 说我可能正在使用无限递归(我很确定我的 prog 没问题)。有什么办法可以处理吗?我试过把[DebuggerNonUserCode]递归方法放在前面,但没有奏效。

忘了说,它是 Visual Studio 2010。

这是我程序中的递归函数。我正在为每个标记为未访问的单元格运行它。

    public static int tmp_lowest_floor = 0;
    public static int tmp_maks_size = 0;

    static void function1(Point[, ,] array, int pos_y, int pos_z, int pos_x) // recursive function
    {
        Point cell = array[pos_y, pos_z, pos_x];

        if (cell.Visited == false && cell.IsCave)
        {
            cell.Visited = true; // changing to visited so we do not count anything for this cell anymore
            tmp_maks_size++; // increasing for each cell in this cave (in this run)

            if (tmp_lowest_floor < pos_y) { tmp_lowest_floor = pos_y; }
            cell.FillNeighbourList(array, pos_y, pos_z, pos_x);// adds neighbours into cell's list (max 6) up, down, north, east, south, west

            foreach (Point p in cell.neighbours) // max 6 times recursion in here (I know it sounds horrible, but once I check all the neighbours for a cell, I'll not have to check it ever again)
            {
                if (p != null)
                {
                    if (p.IsCave == true && p.Visited == false)
                    {
                        function1(tablica, p.pos_y, p.pos_z, p.pos_x);
                    }
                }
            }

        }

    }

ps 我知道我可以用迭代的方式来做,但是,作业说它必须用递归来完成

4

3 回答 3

7

你不能忽视它,你真的把堆栈搞砸了。

您所做的是要么增加堆栈(从而延迟问题),要么意识到手头的问题是算法的一个非常糟糕的实现并修复它(例如,通过使用迭代方法,或利用尾调用递归) .

顺便说一句,想知道您使用多少堆栈来遍历 200x200x200 阵列中的每个单元格,只跟踪您的 x、y 和 z 坐标,仅此而已?96MB。Windows 默认为您提供 1MB 宽的堆栈。

编辑:要解决您的特定问题,您拥有的是一个非常基本的填充算法。它的迭代形式使用队列和列表。在伪代码中:

list visited=[];
queue q=[];

q.push(startnode);           // the starting point
while(!q.empty())
{
  // make sure we don't revisit nodes
  if(visited.contains(node))
     continue;

  visited.add(node=q.pop()); // we just visited the top

  // do your conditions here, the cave thing? no clue what that is
  // if it passes your filter, do any extra operations on your node here (none in your code)

  // and push the neighbours in the queue
  q.push_all(node.get_neighbours());
}
于 2012-11-06T20:15:33.030 回答
4

运行时环境具有有限堆栈。每次调用方法时,都会将更多数据添加到该堆栈中。每次方法返回时,数据都会从堆栈中删除。如果您在方法中的方法中继续调用方法并且这些方法没有返回,最终您的堆栈将耗尽空间,您将获得堆栈溢出。

如果你想避免这种情况,你真的只需要修改你的算法以使用更少的递归(在方法中调用方法),或者满足于使用足够小的数据集,你的堆栈不会变得太大。

于 2012-11-06T20:15:51.320 回答
1

您可以通过以下方式增加堆栈大小:

  • 右键单击您的项目
  • 选择属性 -> 配置属性 -> 链接器 -> 系统
  • 为“堆栈保留大小”和“堆栈提交大小”设置不同的值(以字节为单位)。从这里您还可以更改堆大小。

在这个问题中,我遇到了与尾递归类似的问题

于 2015-09-11T12:35:00.563 回答