简短版
我认为深度优先搜索算法可能会对你有所帮助。
在你的情况下,每个方块可以被看作是图的一个节点,如果它们共享一条边或一个角,那么它们之间存在一条边。
我找到了一段很好的视频,解释了这个算法的工作原理:Depth First Search on youtube
DFS算法可能与你尝试使用递归方法的方式非常相似,但关键的区别在于,在算法进行时,你会“着色”所访问的节点/方块。建议你将探索过的节点作为每个方块的属性,而不是将其保存在单独的数据结构中。
然后,如果你遇到了一个已经访问过的方块,就不要再去探索它了。如果你已经探索完了当前节点的所有邻居,就回到你之前正在探索的节点,并继续探索它的邻居(递归),直到你回溯到从哪里开始算法的节点。
与你的特定问题相关的更多细节
检测邻居
你提到你的正方形存储在ArrayList中,这很好。但是它并不能防止你构建一个二维正方形数组,其中如果没有正方形,则单元格为null;如果有正方形,则包含位于该位置的正方形实例的引用。依我之见,这将使查找邻居比查找每对正方形之间的碰撞容易得多(我认为这是你现在正在做的事情)。
您不必在程序中使用这样的二维数组。我非常有信心,这会让大量正方形的操作更快。
当然,还有其他数据结构可以轻松查找图节点之间的交点。例如,您可以构建一个
邻接矩阵,然后将其用于任何后续计算,但您不必这样做。
使用您的示例运行DFS
我将使用堆栈来跟踪我在瓷砖探索中的位置。我将按其坐标引用瓷砖。从您的图中以红色突出显示,并具有坐标(1,2)的单元格是我们开始算法的单元格。
算法如下:
while (!stack.isEmpty()) {
currentTyle = stack.top();
boolean currentHasNeighborsToExplore = false;
for (n in neighbors of currentTyle) {
if (n is not explored) {
n is explored;
stack.add(n);
currentHasNeighborsToExplore = true;
break;
}
}
if (!currentHasNeighborsToExplore) {
stack.pop();
}
}
我们从初始样式(1,2)开始算法。
第一步:
栈:[(1,2)]
栈顶是(1,2)。
(1,2)有未被探索的邻居n:(2,2)。
现在,(2,2)被探索过了,我们将其添加到堆栈中并进行下一步。
第二步:
栈:[(1,2) (2,2)]
栈顶是(2,2)。
(2,2)有已被探索的邻居n:(1,2)。
(2,2)有未被探索的邻居n:(3,1)。
现在,(3,1)被探索过了,我们将其添加到堆栈中并进行下一步。
第三步:
栈:[(1,2) (2,2) (3,1)]
栈顶是(3,1)。
(3,1)有已被探索的邻居n:(2,2)。
(3,1)有邻居n: (4,2),它是未探索的
(4,2)现在被探索了,我们将其添加到栈中并进行下一步
第4步
栈:[(1,2) (2,2) (3,1) (4,2)]
栈顶是(4,2)
(4,2)有邻居n: (4,3),它是未探索的
(4,3)现在被探索了,我们将其添加到栈中并进行下一步
第5步
栈:[(1,2) (2,2) (3,1) (4,2) (4,3)]
栈顶是(4,3)
(4,3)有邻居n: (4,2),它已经被探索了
(4,3)没有未探索的邻居,我们从栈中弹出它并进行下一步
第6步
栈:[(1,2) (2,2) (3,1) (4,2)]
栈顶是(2,2)
(4,2)的邻居n是(4,3),已被探索
(4,2)的邻居n是(5,1),未被探索
(5,1)现在已被探索,我们将其添加到栈中并进行下一步
下一步
在下一步中,(5,1)没有未探索的邻居,它将从栈中弹出,因为没有剩余未探索的邻居。