洪水填充优化:尝试使用队列

时间:2012-09-23 11:47:37

标签: java recursion queue flood-fill

我正在尝试创建一个填充方法,该方法采用用户指定的初始坐标,检查字符然后根据需要进行更改。在这样做之后,它然后检查相邻的正方形并重复该过程。经过一些研究,我遇到了泛洪填充算法,并在尝试之后(它可以工作,但不能满足我250到250个字符数组的最大要求)。

我的原始洪水填充算法如下:

public static void fillArea (int x, int y, char original, char fill){

   if (picture[y-1][x-1] != original){
      return;
   }
   picture[y-1][x-1] = fill;
   fillArea (x-1, y, original, fill);
   fillArea (x+1, y, original, fill);
   fillArea (x, y-1, original, fill);
   fillArea (x, y+1, original, fill);

   return;
}

经过测试,我开始尝试使用Wikipediathis question asked previously中有关类似问题的解释的队列方法。到目前为止,我已经提出了以下代码:

public static void fillArea (int x, int y, char original, char fill){
  if (x != 0)
     x--;
  if (y!= 0)
     y--;
  Queue<Point> queue = new LinkedList<Point>();
  if (picture[y][x] != original){
      return;
  }
  queue.add(new Point(x, y));

  while (!queue.isEmpty()){
      Point p = queue.remove();
      if (picture[p.y][p.x] == original){
         picture[p.y][p.x] = fill;
         queue.add(new Point(p.x-1, p.y));
         queue.add(new Point(p.x+1, p.y));
         queue.add(new Point(p.x, p.y-1));
         queue.add(new Point(p.x, p.y+1));
      }
   }

   return;
}

虽然第一个递归方法能够用于较小的值,但是当数组太大时它不起作用。然而,第二种方法让我陷入某种无限循环,由于我对队列缺乏经验,我无法识别。如何优化第一个代码示例以使用较大的样本或修复第二个代码样本以便得到结果?任何人都可以解释如何编码这两个中的任何一个或我做错了什么?

谢谢!

编辑:我能够在第二个代码中找到无限循环错误(它已被修复),但基于队列的方法没有填满整个区域。实际上,它比基于递归的方法填充的区域更少。 编辑2:它现在适用于方阵。我怎样才能确保它适用于矩形阵列(第二种方法)。

2 个答案:

答案 0 :(得分:1)

不应该

if (picture[p.y][p.x] == original){
     picture[p.y-1][p.x-1] = fill;

if (picture[p.y][p.x] == original){
     picture[p.y][p.x] = fill;
队列中的

- 方法?

答案 1 :(得分:1)

作为参考,通过在处理的数组周围添加缓冲区边界来修复问题。例如,如果要填充的数组是

000
000
000

它被制作成

   #####
   #000#
   #000#
   #000#
   #####

在被处理之前。