将多重递归方法转换为迭代

时间:2015-03-07 12:29:48

标签: java recursion iteration stack-overflow

我知道有很多次问过类似的答案,但我的情况并不那么简单。

我有一个递归方法,可以调用自己4次(“最坏情况”)。我正在努力避免递归,因为它导致了StackOverFlowException,但我找不到用while循环或类似方法替换它的方法。

这甚至可能吗?据我所知,你只能使用while循环向一个方向移动而不是向所有方向“流动”(深度优先搜索实际上)。

以下是代码:

private static void searchNeighboringPixels(int x, int y, int[][] arr) {
        arr[y][x] = 2;
        if (x+1 < arr[y].length && arr[y][x+1] == 1) {
            searchNeighboringPixels(x+1, y, arr);
            //...do other things
        }
        if (x-1 > 0 && arr[y][x-1] == 1) {
            searchNeighboringPixels(x-1, y, arr);
            //...do other things
        }
        if (y+1 < arr.length && arr[y+1][x] == 1) {
            searchNeighboringPixels(x, y+1, arr);
            //...do other things
        }
        if (y-1 > 0 && arr[y-1][x] == 1) {
            searchNeighboringPixels(x, y-1, arr);
            //...do other things
        }
    }

我在这做什么:

  1. 在“二进制图片”中(此处为示例,它变成了2D-int数组)我正在寻找特定的黑色像素,直到我得到所有连接的黑色像素。
  2. 黑色的值为1,白色的值为0.我已访问过的像素值将设置为值2(以便稍后处理)。
  3. 此算法进行“depht-first search”,直到找到所有连接的黑色像素(并排)

2 个答案:

答案 0 :(得分:4)

使用Stack可以始终避免递归:

  • 而不是对searchNeighboringPixels(x, y, arr)进行递归调用,将点(x,y)放在堆栈中。

  • 使用while循环包装您的4个条件,该循环一直运行直到Stack为空。

  • 每次迭代都会弹出堆栈的顶部,并将该点视为当前点。

这样的事情:

private static void searchNeighboringPixels(int x, int y, int[][] arr) {
    Stack<Point> points = new Stack<>();
    points.push(new Point(x,y));
    while (!points.isEmpty()) {
        Point p = points.pop();
        x = p.getX();
        y = p.getY();
        arr[y][x] = 2;
        if (x+1 < arr[y].length && arr[y][x+1] == 1) {
            points.push(new Point(x+1,y);
            //...do other things
        }
        if (x-1 > 0 && arr[y][x-1] == 1) {
            points.push(new Point(x-1,y);
            //...do other things
        }
        if (y+1 < arr.length && arr[y+1][x] == 1) {
            points.push(new Point(x,y+1);
            //...do other things
        }
        if (y-1 > 0 && arr[y-1][x] == 1) {
            points.push(new Point(x,y-1);
            //...do other things
        }
    }
}

答案 1 :(得分:1)

你说你正在进行深度优先搜索。这个问题有许多定义明确的迭代方法,其中大部分基于某种形式的QueueStack本地保存在方法而不是调用堆栈中。正如您所知,基于队列的方法的优点是Queue不会受到递归解决方案对堆栈空间的相同限制。

此排序深度优先搜索taken from wikipedia的伪代码:

  

DFS的非递归实现:[6]

     

输入:图G和G

的顶点v      

输出:从v标记为已发现的所有顶点

1  procedure DFS-iterative(G,v):
2      let S be a stack
3      S.push(v)
4      while S is not empty
5            v = S.pop() 
6            if v is not labeled as discovered:
7                label v as discovered
8                for all edges from v to w in G.adjacentEdges(v) do
9                    S.push(w)