我知道有很多次问过类似的答案,但我的情况并不那么简单。
我有一个递归方法,可以调用自己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
}
}
我在这做什么:
答案 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)
你说你正在进行深度优先搜索。这个问题有许多定义明确的迭代方法,其中大部分基于某种形式的Queue
或Stack
本地保存在方法而不是调用堆栈中。正如您所知,基于队列的方法的优点是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)